]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/pcm.c
mpegts: log into an AVFormatContext rather than MpegTSContext.
[ffmpeg] / libavcodec / pcm.c
index 746a520256a708d7d8401151ce0db2e7f3b5ccc7..2ad395dd0e8c1abd38ab91c9842052776d2a5502 100644 (file)
@@ -2,20 +2,20 @@
  * PCM codecs
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of FFmpeg.
+ * This file is part of Libav.
  *
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -71,7 +71,7 @@ static av_cold int pcm_encode_close(AVCodecContext *avctx)
  * @param offset Sample value offset
  */
 #define ENCODE(type, endian, src, dst, n, shift, offset) \
-    samples_##type = (type*)src; \
+    samples_##type = (const type*) src; \
     for(;n>0;n--) { \
         register type v = (*samples_##type++ >> shift) + offset; \
         bytestream_put_##endian(&dst, v); \
@@ -81,14 +81,14 @@ static int pcm_encode_frame(AVCodecContext *avctx,
                             unsigned char *frame, int buf_size, void *data)
 {
     int n, sample_size, v;
-    short *samples;
+    const short *samples;
     unsigned char *dst;
-    uint8_t *srcu8;
-    int16_t *samples_int16_t;
-    int32_t *samples_int32_t;
-    int64_t *samples_int64_t;
-    uint16_t *samples_uint16_t;
-    uint32_t *samples_uint32_t;
+    const uint8_t *srcu8;
+    const int16_t *samples_int16_t;
+    const int32_t *samples_int32_t;
+    const int64_t *samples_int64_t;
+    const uint16_t *samples_uint16_t;
+    const uint32_t *samples_uint32_t;
 
     sample_size = av_get_bits_per_sample(avctx->codec->id)/8;
     n = buf_size / sample_size;
@@ -227,6 +227,10 @@ static av_cold int pcm_decode_init(AVCodecContext * avctx)
     }
 
     avctx->sample_fmt = avctx->codec->sample_fmts[0];
+
+    if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
+        avctx->bits_per_raw_sample = av_get_bits_per_sample(avctx->codec->id);
+
     return 0;
 }
 
@@ -255,7 +259,7 @@ static int pcm_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     PCMDecode *s = avctx->priv_data;
-    int sample_size, c, n;
+    int sample_size, c, n, i;
     short *samples;
     const uint8_t *src, *src8, *src2[MAX_CHANNELS];
     uint8_t *dstu8;
@@ -284,6 +288,14 @@ static int pcm_decode_frame(AVCodecContext *avctx,
     if (CODEC_ID_PCM_DVD == avctx->codec_id)
         /* 2 samples are interleaved per block in PCM_DVD */
         sample_size = avctx->bits_per_coded_sample * 2 / 8;
+    else if (avctx->codec_id == CODEC_ID_PCM_LXF)
+        /* we process 40-bit blocks per channel for LXF */
+        sample_size = 5;
+
+    if (sample_size == 0) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid sample_size\n");
+        return AVERROR(EINVAL);
+    }
 
     n = avctx->channels * sample_size;
 
@@ -428,10 +440,29 @@ static int pcm_decode_frame(AVCodecContext *avctx,
         default:
             av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n");
             return -1;
-            break;
         }
         samples = (short *) dst_int32_t;
         break;
+    case CODEC_ID_PCM_LXF:
+        dst_int32_t = data;
+        n /= avctx->channels;
+        //unpack and de-planerize
+        for (i = 0; i < n; i++) {
+            for (c = 0, src8 = src + i*5; c < avctx->channels; c++, src8 += n*5) {
+                //extract low 20 bits and expand to 32 bits
+                *dst_int32_t++ = (src8[2] << 28) | (src8[1] << 20) | (src8[0] << 12) |
+                                 ((src8[2] & 0xF) << 8) | src8[1];
+            }
+
+            for (c = 0, src8 = src + i*5; c < avctx->channels; c++, src8 += n*5) {
+                //extract high 20 bits and expand to 32 bits
+                *dst_int32_t++ = (src8[4] << 24) | (src8[3] << 16) |
+                                 ((src8[2] & 0xF0) << 8) | (src8[4] << 4) | (src8[3] >> 4);
+            }
+        }
+        src += n * avctx->channels * 5;
+        samples = (short *) dst_int32_t;
+        break;
     default:
         return -1;
     }
@@ -440,66 +471,63 @@ static int pcm_decode_frame(AVCodecContext *avctx,
 }
 
 #if CONFIG_ENCODERS
-#define PCM_ENCODER(id,sample_fmt_,name,long_name_) \
-AVCodec name ## _encoder = {                    \
-    #name,                                      \
-    AVMEDIA_TYPE_AUDIO,                         \
-    id,                                         \
-    0,                                          \
-    pcm_encode_init,                            \
-    pcm_encode_frame,                           \
-    pcm_encode_close,                           \
-    NULL,                                       \
-    .sample_fmts = (const enum SampleFormat[]){sample_fmt_,SAMPLE_FMT_NONE}, \
+#define PCM_ENCODER(id_,sample_fmt_,name_,long_name_) \
+AVCodec ff_ ## name_ ## _encoder = {            \
+    .name        = #name_,                      \
+    .type        = AVMEDIA_TYPE_AUDIO,          \
+    .id          = id_,                         \
+    .init        = pcm_encode_init,             \
+    .encode      = pcm_encode_frame,            \
+    .close       = pcm_encode_close,            \
+    .sample_fmts = (const enum AVSampleFormat[]){sample_fmt_,AV_SAMPLE_FMT_NONE}, \
     .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
-};
+}
 #else
 #define PCM_ENCODER(id,sample_fmt_,name,long_name_)
 #endif
 
 #if CONFIG_DECODERS
-#define PCM_DECODER(id,sample_fmt_,name,long_name_)         \
-AVCodec name ## _decoder = {                    \
-    #name,                                      \
-    AVMEDIA_TYPE_AUDIO,                         \
-    id,                                         \
-    sizeof(PCMDecode),                          \
-    pcm_decode_init,                            \
-    NULL,                                       \
-    NULL,                                       \
-    pcm_decode_frame,                           \
-    .sample_fmts = (const enum SampleFormat[]){sample_fmt_,SAMPLE_FMT_NONE}, \
+#define PCM_DECODER(id_,sample_fmt_,name_,long_name_)         \
+AVCodec ff_ ## name_ ## _decoder = {            \
+    .name           = #name_,                   \
+    .type           = AVMEDIA_TYPE_AUDIO,       \
+    .id             = id_,                      \
+    .priv_data_size = sizeof(PCMDecode),        \
+    .init           = pcm_decode_init,          \
+    .decode         = pcm_decode_frame,         \
+    .sample_fmts = (const enum AVSampleFormat[]){sample_fmt_,AV_SAMPLE_FMT_NONE}, \
     .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
-};
+}
 #else
 #define PCM_DECODER(id,sample_fmt_,name,long_name_)
 #endif
 
 #define PCM_CODEC(id, sample_fmt_, name, long_name_)         \
-    PCM_ENCODER(id,sample_fmt_,name,long_name_) PCM_DECODER(id,sample_fmt_,name,long_name_)
+    PCM_ENCODER(id,sample_fmt_,name,long_name_); PCM_DECODER(id,sample_fmt_,name,long_name_)
 
 /* Note: Do not forget to add new entries to the Makefile as well. */
-PCM_CODEC  (CODEC_ID_PCM_ALAW,  SAMPLE_FMT_S16, pcm_alaw, "PCM A-law");
-PCM_CODEC  (CODEC_ID_PCM_DVD,   SAMPLE_FMT_S32, pcm_dvd, "PCM signed 20|24-bit big-endian");
-PCM_CODEC  (CODEC_ID_PCM_F32BE, SAMPLE_FMT_FLT, pcm_f32be, "PCM 32-bit floating point big-endian");
-PCM_CODEC  (CODEC_ID_PCM_F32LE, SAMPLE_FMT_FLT, pcm_f32le, "PCM 32-bit floating point little-endian");
-PCM_CODEC  (CODEC_ID_PCM_F64BE, SAMPLE_FMT_DBL, pcm_f64be, "PCM 64-bit floating point big-endian");
-PCM_CODEC  (CODEC_ID_PCM_F64LE, SAMPLE_FMT_DBL, pcm_f64le, "PCM 64-bit floating point little-endian");
-PCM_CODEC  (CODEC_ID_PCM_MULAW, SAMPLE_FMT_S16, pcm_mulaw, "PCM mu-law");
-PCM_CODEC  (CODEC_ID_PCM_S8,    SAMPLE_FMT_U8,  pcm_s8, "PCM signed 8-bit");
-PCM_CODEC  (CODEC_ID_PCM_S16BE, SAMPLE_FMT_S16, pcm_s16be, "PCM signed 16-bit big-endian");
-PCM_CODEC  (CODEC_ID_PCM_S16LE, SAMPLE_FMT_S16, pcm_s16le, "PCM signed 16-bit little-endian");
-PCM_DECODER(CODEC_ID_PCM_S16LE_PLANAR, SAMPLE_FMT_S16, pcm_s16le_planar, "PCM 16-bit little-endian planar");
-PCM_CODEC  (CODEC_ID_PCM_S24BE, SAMPLE_FMT_S32, pcm_s24be, "PCM signed 24-bit big-endian");
-PCM_CODEC  (CODEC_ID_PCM_S24DAUD, SAMPLE_FMT_S16,  pcm_s24daud, "PCM D-Cinema audio signed 24-bit");
-PCM_CODEC  (CODEC_ID_PCM_S24LE, SAMPLE_FMT_S32, pcm_s24le, "PCM signed 24-bit little-endian");
-PCM_CODEC  (CODEC_ID_PCM_S32BE, SAMPLE_FMT_S32, pcm_s32be, "PCM signed 32-bit big-endian");
-PCM_CODEC  (CODEC_ID_PCM_S32LE, SAMPLE_FMT_S32, pcm_s32le, "PCM signed 32-bit little-endian");
-PCM_CODEC  (CODEC_ID_PCM_U8,    SAMPLE_FMT_U8,  pcm_u8, "PCM unsigned 8-bit");
-PCM_CODEC  (CODEC_ID_PCM_U16BE, SAMPLE_FMT_S16, pcm_u16be, "PCM unsigned 16-bit big-endian");
-PCM_CODEC  (CODEC_ID_PCM_U16LE, SAMPLE_FMT_S16, pcm_u16le, "PCM unsigned 16-bit little-endian");
-PCM_CODEC  (CODEC_ID_PCM_U24BE, SAMPLE_FMT_S32, pcm_u24be, "PCM unsigned 24-bit big-endian");
-PCM_CODEC  (CODEC_ID_PCM_U24LE, SAMPLE_FMT_S32, pcm_u24le, "PCM unsigned 24-bit little-endian");
-PCM_CODEC  (CODEC_ID_PCM_U32BE, SAMPLE_FMT_S32, pcm_u32be, "PCM unsigned 32-bit big-endian");
-PCM_CODEC  (CODEC_ID_PCM_U32LE, SAMPLE_FMT_S32, pcm_u32le, "PCM unsigned 32-bit little-endian");
-PCM_CODEC  (CODEC_ID_PCM_ZORK,  SAMPLE_FMT_S16, pcm_zork, "PCM Zork");
+PCM_CODEC  (CODEC_ID_PCM_ALAW,  AV_SAMPLE_FMT_S16, pcm_alaw, "PCM A-law");
+PCM_DECODER(CODEC_ID_PCM_DVD,   AV_SAMPLE_FMT_S32, pcm_dvd, "PCM signed 20|24-bit big-endian");
+PCM_CODEC  (CODEC_ID_PCM_F32BE, AV_SAMPLE_FMT_FLT, pcm_f32be, "PCM 32-bit floating point big-endian");
+PCM_CODEC  (CODEC_ID_PCM_F32LE, AV_SAMPLE_FMT_FLT, pcm_f32le, "PCM 32-bit floating point little-endian");
+PCM_CODEC  (CODEC_ID_PCM_F64BE, AV_SAMPLE_FMT_DBL, pcm_f64be, "PCM 64-bit floating point big-endian");
+PCM_CODEC  (CODEC_ID_PCM_F64LE, AV_SAMPLE_FMT_DBL, pcm_f64le, "PCM 64-bit floating point little-endian");
+PCM_DECODER(CODEC_ID_PCM_LXF,   AV_SAMPLE_FMT_S32, pcm_lxf, "PCM signed 20-bit little-endian planar");
+PCM_CODEC  (CODEC_ID_PCM_MULAW, AV_SAMPLE_FMT_S16, pcm_mulaw, "PCM mu-law");
+PCM_CODEC  (CODEC_ID_PCM_S8,    AV_SAMPLE_FMT_U8,  pcm_s8, "PCM signed 8-bit");
+PCM_CODEC  (CODEC_ID_PCM_S16BE, AV_SAMPLE_FMT_S16, pcm_s16be, "PCM signed 16-bit big-endian");
+PCM_CODEC  (CODEC_ID_PCM_S16LE, AV_SAMPLE_FMT_S16, pcm_s16le, "PCM signed 16-bit little-endian");
+PCM_DECODER(CODEC_ID_PCM_S16LE_PLANAR, AV_SAMPLE_FMT_S16, pcm_s16le_planar, "PCM 16-bit little-endian planar");
+PCM_CODEC  (CODEC_ID_PCM_S24BE, AV_SAMPLE_FMT_S32, pcm_s24be, "PCM signed 24-bit big-endian");
+PCM_CODEC  (CODEC_ID_PCM_S24DAUD, AV_SAMPLE_FMT_S16,  pcm_s24daud, "PCM D-Cinema audio signed 24-bit");
+PCM_CODEC  (CODEC_ID_PCM_S24LE, AV_SAMPLE_FMT_S32, pcm_s24le, "PCM signed 24-bit little-endian");
+PCM_CODEC  (CODEC_ID_PCM_S32BE, AV_SAMPLE_FMT_S32, pcm_s32be, "PCM signed 32-bit big-endian");
+PCM_CODEC  (CODEC_ID_PCM_S32LE, AV_SAMPLE_FMT_S32, pcm_s32le, "PCM signed 32-bit little-endian");
+PCM_CODEC  (CODEC_ID_PCM_U8,    AV_SAMPLE_FMT_U8,  pcm_u8, "PCM unsigned 8-bit");
+PCM_CODEC  (CODEC_ID_PCM_U16BE, AV_SAMPLE_FMT_S16, pcm_u16be, "PCM unsigned 16-bit big-endian");
+PCM_CODEC  (CODEC_ID_PCM_U16LE, AV_SAMPLE_FMT_S16, pcm_u16le, "PCM unsigned 16-bit little-endian");
+PCM_CODEC  (CODEC_ID_PCM_U24BE, AV_SAMPLE_FMT_S32, pcm_u24be, "PCM unsigned 24-bit big-endian");
+PCM_CODEC  (CODEC_ID_PCM_U24LE, AV_SAMPLE_FMT_S32, pcm_u24le, "PCM unsigned 24-bit little-endian");
+PCM_CODEC  (CODEC_ID_PCM_U32BE, AV_SAMPLE_FMT_S32, pcm_u32be, "PCM unsigned 32-bit big-endian");
+PCM_CODEC  (CODEC_ID_PCM_U32LE, AV_SAMPLE_FMT_S32, pcm_u32le, "PCM unsigned 32-bit little-endian");
+PCM_CODEC  (CODEC_ID_PCM_ZORK,  AV_SAMPLE_FMT_S16, pcm_zork, "PCM Zork");