[FFmpeg-devel] [PATCH]Support DVD-A files containing LPCM

Carl Eugen Hoyos cehoyos at ag.or.at
Wed Jul 31 01:34:54 CEST 2013


On Monday 29 July 2013 08:29:09 pm Kirill Gavrilov wrote:
> On Mon, Jul 29, 2013 at 3:18 PM, Carl Eugen Hoyos <cehoyos at ag.or.at> wrote:
> > I cannot implement >16bit or multichannel without samples.
>
> If it was request - you can try this 10 MiB cut sample:
> http://sview.cifro-city.ru/trash/ats.AOB

Thank you!

New patch attached, 20bit is untested.

Please review, Carl Eugen
-------------- next part --------------
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 5d5b09f..f486384 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -581,6 +581,48 @@ static int mpegps_read_packet(AVFormatContext *s,
                 goto skip;
             avio_skip(s->pb, 6);
             len -=6;
+      } else if (lpcm_header_len > 8 && startcode == 0xa0) {
+          // DVD-A LPCM audio
+          int sample_rates[] = { 48000, 96000, 192000,
+                                 0, 0, 0, 0, 0,
+                                 44100, 88200, 176400 };
+          unsigned sample_rate, channels;
+          avio_skip(s->pb, 2); // Pointer to start of audio frame
+          avio_skip(s->pb, 1); // Unknown
+          switch (avio_r8(s->pb) >> 4) {
+          case 2:
+              st->codec->codec_id = AV_CODEC_ID_PCM_DVD;
+              st->codec->bits_per_coded_sample = 24;
+              break;
+          case 1:
+              st->codec->codec_id = AV_CODEC_ID_PCM_DVD;
+              st->codec->bits_per_coded_sample = 20;
+              break;
+          case 0:
+              st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
+              st->codec->bits_per_coded_sample = 16;
+              break;
+          default:
+              len -= 4;
+              goto skip;
+          }
+          sample_rate = avio_r8(s->pb) >> 4;
+          len -= 5;
+          if (sample_rate > 10)
+              goto skip;
+          st->codec->sample_rate = sample_rates[sample_rate];
+          if (!st->codec->sample_rate)
+              goto skip;
+          avio_skip(s->pb, 1); // Unknown
+          channels = avio_r8(s->pb);
+          len -= 2;
+          if (channels > 1) {
+              avpriv_request_sample(s, "Multichannel DVD-A LPCM audio");
+              return AVERROR_PATCHWELCOME;
+          }
+          st->codec->channels = channels + 1;
+          avio_skip(s->pb, lpcm_header_len - 7);
+          len -= lpcm_header_len - 7;
       } else {
         int b1, freq;
 


More information about the ffmpeg-devel mailing list