Merge commit 'a42e3a6700547e4e49445bda81d3a89ec3e081a9'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 1 Sep 2013 11:00:08 +0000 (13:00 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 1 Sep 2013 11:00:08 +0000 (13:00 +0200)
* commit 'a42e3a6700547e4e49445bda81d3a89ec3e081a9':
  pcm_dvd: consolidate pieces from pcm.c and mpeg.c

Conflicts:
libavcodec/pcm.c
libavcodec/version.h
libavformat/mpeg.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/Makefile
libavcodec/pcm-dvd.c
libavcodec/pcm.c
libavcodec/version.h
libavformat/mpeg.c

Simple merge
index 0000000,8e88ad4..b34b748
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,287 +1,289 @@@
 - * This file is part of Libav.
+ /*
+  * LPCM codecs for PCM formats found in Video DVD streams
+  * Copyright (c) 2009-2013 Christian Schmidt
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg 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.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg 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
 -        av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n");
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ /**
+  * @file
+  * LPCM codecs for PCM formats found in Video DVD streams
+  */
+ #include "avcodec.h"
+ #include "bytestream.h"
+ #include "internal.h"
+ typedef struct PCMDVDContext {
+     uint32_t last_header;    // Cached header to see if parsing is needed
+     int block_size;          // Size of a block of samples in bytes
+     int samples_per_block;   // Number of samples per channel per block
+     int groups_per_block;    // Number of 20/24bit sample groups per block
+     uint8_t *extra_samples;  // Pointer to leftover samples from a frame
+     int extra_sample_count;  // Number of leftover samples in the buffer
+ } PCMDVDContext;
+ static av_cold int pcm_dvd_decode_init(AVCodecContext *avctx)
+ {
+     PCMDVDContext *s = avctx->priv_data;
+     /* Invalid header to force parsing of the first header */
+     s->last_header = -1;
+     /* reserve space for 8 channels, 3 bytes/sample, 4 samples/block */
+     if (!(s->extra_samples = av_malloc(8 * 3 * 4)))
+         return AVERROR(ENOMEM);
+     s->extra_sample_count = 0;
+     return 0;
+ }
+ static av_cold int pcm_dvd_decode_uninit(AVCodecContext *avctx)
+ {
+     PCMDVDContext *s = avctx->priv_data;
+     if (s->extra_samples)
+         av_free(s->extra_samples);
+     return 0;
+ }
+ static int pcm_dvd_parse_header(AVCodecContext *avctx, const uint8_t *header)
+ {
+     /* no traces of 44100 and 32000Hz in any commercial software or player */
+     static const uint32_t frequencies[4] = { 48000, 96000, 44100, 32000 };
+     PCMDVDContext *s = avctx->priv_data;
+     int header_int = (header[0] & 0xe0) | (header[1] << 8) | (header[2] << 16);
+     /* early exit if the header didn't change apart from the frame number */
+     if (s->last_header == header_int)
+         return 0;
+     if (avctx->debug & FF_DEBUG_PICT_INFO)
+         av_dlog(avctx, "pcm_dvd_parse_header: header = %02x%02x%02x\n",
+                 header[0], header[1], header[2]);
+     /*
+      * header[0] emphasis (1), muse(1), reserved(1), frame number(5)
+      * header[1] quant (2), freq(2), reserved(1), channels(3)
+      * header[2] dynamic range control (0x80 = off)
+      */
+     /* get the sample depth and derive the sample format from it */
+     avctx->bits_per_coded_sample = 16 + (header[1] >> 6 & 3) * 4;
+     if (avctx->bits_per_coded_sample == 28) {
++        av_log(avctx, AV_LOG_ERROR,
++               "PCM DVD unsupported sample depth %i\n",
++               avctx->bits_per_coded_sample);
+         return AVERROR_INVALIDDATA;
+     }
+     avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16
+                                                            : AV_SAMPLE_FMT_S32;
+     avctx->bits_per_raw_sample = avctx->bits_per_coded_sample;
+     /* get the sample rate */
+     avctx->sample_rate = frequencies[header[1] >> 4 & 3];
+     /* get the number of channels */
+     avctx->channels = 1 + (header[1] & 7);
+     /* calculate the bitrate */
+     avctx->bit_rate = avctx->channels *
+                       avctx->sample_rate *
+                       avctx->bits_per_coded_sample;
+     /* 4 samples form a group in 20/24bit PCM on DVD Video.
+      * A block is formed by the number of groups that are
+      * needed to complete a set of samples for each channel. */
+     if (avctx->bits_per_coded_sample == 16) {
+         s->samples_per_block = 1;
+         s->block_size        = avctx->channels * 2;
+     } else {
+         switch (avctx->channels) {
+         case 1:
+         case 2:
+         case 4:
+             /* one group has all the samples needed */
+             s->block_size        = 4 * avctx->bits_per_coded_sample / 8;
+             s->samples_per_block = 4 / avctx->channels;
+             s->groups_per_block  = 1;
+             break;
+         case 8:
+             /* two groups have all the samples needed */
+             s->block_size        = 8 * avctx->bits_per_coded_sample / 8;
+             s->samples_per_block = 1;
+             s->groups_per_block  = 2;
+             break;
+         default:
+             /* need avctx->channels groups */
+             s->block_size        = 4 * avctx->channels *
+                                    avctx->bits_per_coded_sample / 8;
+             s->samples_per_block = 4;
+             s->groups_per_block  = avctx->channels;
+             break;
+         }
+     }
+     if (avctx->debug & FF_DEBUG_PICT_INFO)
+         av_dlog(avctx,
+                 "pcm_dvd_parse_header: %d channels, %d bits per sample, %d Hz, %d bit/s\n",
+                 avctx->channels, avctx->bits_per_coded_sample,
+                 avctx->sample_rate, avctx->bit_rate);
+     s->last_header = header_int;
+     return 0;
+ }
+ static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src,
+                                     void *dst, int blocks)
+ {
+     PCMDVDContext *s = avctx->priv_data;
+     int16_t *dst16   = dst;
+     int32_t *dst32   = dst;
+     GetByteContext gb;
+     int i;
+     uint8_t t;
+     int samples;
+     bytestream2_init(&gb, src, blocks * s->block_size);
+     switch (avctx->bits_per_coded_sample) {
+     case 16:
+ #if HAVE_BIGENDIAN
+         bytestream2_get_buffer(&gb, dst16, blocks * s->block_size);
+         dst16 += blocks * block_size / 2;
+ #else
+         samples = blocks * avctx->channels;
+         do {
+             *dst16++ = bytestream2_get_be16u(&gb);
+         } while (--samples);
+ #endif
+         return dst16;
+     case 20:
+         do {
+             for (i = s->groups_per_block; i; i--) {
+                 dst32[0] = bytestream2_get_be16u(&gb) << 16;
+                 dst32[1] = bytestream2_get_be16u(&gb) << 16;
+                 dst32[2] = bytestream2_get_be16u(&gb) << 16;
+                 dst32[3] = bytestream2_get_be16u(&gb) << 16;
+                 t = bytestream2_get_byteu(&gb);
+                 *dst32 += (t & 0xf0) << 8;
+                 *dst32 += (t & 0x0f) << 12;
+                 t = bytestream2_get_byteu(&gb);
+                 *dst32 += (t & 0xf0) << 8;
+                 *dst32 += (t & 0x0f) << 12;
+             }
+         } while (--blocks);
+         return dst32;
+     case 24:
+         do {
+             for (i = s->groups_per_block; i; i--) {
+                 dst32[0] = bytestream2_get_be16u(&gb) << 16;
+                 dst32[1] = bytestream2_get_be16u(&gb) << 16;
+                 dst32[2] = bytestream2_get_be16u(&gb) << 16;
+                 dst32[3] = bytestream2_get_be16u(&gb) << 16;
+                 *dst32++ += bytestream2_get_byteu(&gb) << 8;
+                 *dst32++ += bytestream2_get_byteu(&gb) << 8;
+                 *dst32++ += bytestream2_get_byteu(&gb) << 8;
+                 *dst32++ += bytestream2_get_byteu(&gb) << 8;
+             }
+         } while (--blocks);
+         return dst32;
+     default:
+         return NULL;
+     }
+ }
+ static int pcm_dvd_decode_frame(AVCodecContext *avctx, void *data,
+                                 int *got_frame_ptr, AVPacket *avpkt)
+ {
+     AVFrame *frame     = data;
+     const uint8_t *src = avpkt->data;
+     int buf_size       = avpkt->size;
+     PCMDVDContext *s   = avctx->priv_data;
+     int retval;
+     int blocks;
+     void *dst;
+     if (buf_size < 3) {
+         av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
+         return AVERROR_INVALIDDATA;
+     }
+     if ((retval = pcm_dvd_parse_header(avctx, src)))
+         return retval;
+     src      += 3;
+     buf_size -= 3;
+     blocks = (buf_size + s->extra_sample_count) / s->block_size;
+     /* get output buffer */
+     frame->nb_samples = blocks * s->samples_per_block;
+     if ((retval = ff_get_buffer(avctx, frame, 0)) < 0) {
+         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+         return retval;
+     }
+     dst = frame->data[0];
+     /* consume leftover samples from last packet */
+     if (s->extra_sample_count) {
+         int missing_samples = s->block_size - s->extra_sample_count;
+         if (buf_size >= missing_samples) {
+             memcpy(s->extra_samples + s->extra_sample_count, src,
+                    missing_samples);
+             dst = pcm_dvd_decode_samples(avctx, s->extra_samples, dst, 1);
+             src += missing_samples;
+             buf_size -= missing_samples;
+             s->extra_sample_count = 0;
+             blocks--;
+         } else {
+             /* new packet still doesn't have enough samples */
+             memcpy(s->extra_samples + s->extra_sample_count, src, buf_size);
+             s->extra_sample_count += buf_size;
+             return avpkt->size;
+         }
+     }
+     /* decode remaining complete samples */
+     if (blocks) {
+         pcm_dvd_decode_samples(avctx, src, dst, blocks);
+         buf_size -= blocks * s->block_size;
+     }
+     /* store leftover samples */
+     if (buf_size) {
+         src += blocks * s->block_size;
+         memcpy(s->extra_samples, src, buf_size);
+         s->extra_sample_count = buf_size;
+     }
+     *got_frame_ptr = 1;
+     return avpkt->size;
+ }
+ AVCodec ff_pcm_dvd_decoder = {
+     .name           = "pcm_dvd",
+     .long_name      = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for DVD media"),
+     .type           = AVMEDIA_TYPE_AUDIO,
+     .id             = AV_CODEC_ID_PCM_DVD,
+     .priv_data_size = sizeof(PCMDVDContext),
+     .init           = pcm_dvd_decode_init,
+     .decode         = pcm_dvd_decode_frame,
+     .close          = pcm_dvd_decode_uninit,
+     .capabilities   = CODEC_CAP_DR1,
+     .sample_fmts    = (const enum AVSampleFormat[]) {
+         AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE
+     }
+ };
@@@ -582,8 -481,7 +540,7 @@@ AVCodec ff_ ## name_ ## _decoder = 
      PCM_DECODER(id, sample_fmt_, name, long_name_)
  
  /* Note: Do not forget to add new entries to the Makefile as well. */
 -PCM_CODEC  (PCM_ALAW,         AV_SAMPLE_FMT_S16, pcm_alaw,         "PCM A-law");
 +PCM_CODEC  (PCM_ALAW,         AV_SAMPLE_FMT_S16, pcm_alaw,         "PCM A-law / G.711 A-law");
- PCM_DECODER(PCM_DVD,          AV_SAMPLE_FMT_S32, pcm_dvd,          "PCM signed 20|24-bit big-endian");
  PCM_CODEC  (PCM_F32BE,        AV_SAMPLE_FMT_FLT, pcm_f32be,        "PCM 32-bit floating point big-endian");
  PCM_CODEC  (PCM_F32LE,        AV_SAMPLE_FMT_FLT, pcm_f32le,        "PCM 32-bit floating point little-endian");
  PCM_CODEC  (PCM_F64BE,        AV_SAMPLE_FMT_DBL, pcm_f64be,        "PCM 64-bit floating point big-endian");
   * Libavcodec version macros.
   */
  
 +#include "libavutil/avutil.h"
 +
  #define LIBAVCODEC_VERSION_MAJOR 55
- #define LIBAVCODEC_VERSION_MINOR  29
 -#define LIBAVCODEC_VERSION_MINOR 18
 -#define LIBAVCODEC_VERSION_MICRO  0
++#define LIBAVCODEC_VERSION_MINOR  30
 +#define LIBAVCODEC_VERSION_MICRO 100
  
  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                 LIBAVCODEC_VERSION_MINOR, \
@@@ -532,12 -453,7 +532,11 @@@ static int mpegps_read_packet(AVFormatC
          codec_id = AV_CODEC_ID_DTS;
      } else if (startcode >= 0xa0 && startcode <= 0xaf) {
          type = AVMEDIA_TYPE_AUDIO;
 -        codec_id = AV_CODEC_ID_PCM_DVD;
 +        if(lpcm_header_len == 6) {
 +            codec_id = AV_CODEC_ID_MLP;
 +        } else {
-             /* 16 bit form will be handled as AV_CODEC_ID_PCM_S16BE */
 +            codec_id = AV_CODEC_ID_PCM_DVD;
 +        }
      } else if (startcode >= 0xb0 && startcode <= 0xbf) {
          type = AVMEDIA_TYPE_AUDIO;
          codec_id = AV_CODEC_ID_TRUEHD;
      st->id = startcode;
      st->codec->codec_type = type;
      st->codec->codec_id = codec_id;
-     if (codec_id != AV_CODEC_ID_PCM_S16BE)
-         st->need_parsing = AVSTREAM_PARSE_FULL;
 +    if (st->codec->codec_id == AV_CODEC_ID_PCM_MULAW) {
 +        st->codec->channels = 1;
 +        st->codec->channel_layout = AV_CH_LAYOUT_MONO;
 +        st->codec->sample_rate = 8000;
 +    }
 +    st->request_probe     = request_probe;
+     st->need_parsing = AVSTREAM_PARSE_FULL;
   found:
      if(st->discard >= AVDISCARD_ALL)
          goto skip;
-       } else {
-         int b1, freq;
-         /* for LPCM, we just skip the header and consider it is raw
-            audio data */
-         if (len <= 3)
-             goto skip;
-         avio_r8(s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */
-         b1 = avio_r8(s->pb); /* quant (2), freq(2), reserved(1), channels(3) */
-         avio_r8(s->pb); /* dynamic range control (0x80 = off) */
-         len -= 3;
-         freq = (b1 >> 4) & 3;
-         st->codec->sample_rate = lpcm_freq_tab[freq];
-         st->codec->channels = 1 + (b1 & 7);
-         st->codec->bits_per_coded_sample = 16 + ((b1 >> 6) & 3) * 4;
-         st->codec->bit_rate = st->codec->channels *
-                               st->codec->sample_rate *
-                               st->codec->bits_per_coded_sample;
-         if (st->codec->bits_per_coded_sample == 16)
-             st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
-         else if (st->codec->bits_per_coded_sample == 28)
-             return AVERROR(EINVAL);
 +    if (startcode >= 0xa0 && startcode <= 0xaf) {
 +      if (lpcm_header_len == 6 && st->codec->codec_id == AV_CODEC_ID_MLP) {
 +            if (len < 6)
 +                goto skip;
 +            avio_skip(s->pb, 6);
 +            len -=6;
 +      }
 +    }
      ret = av_get_packet(s->pb, pkt, len);
      pkt->pts = pts;
      pkt->dts = dts;