[FFmpeg-cvslog] Support decoding AC-3 in wav.

Carl Eugen Hoyos git at videolan.org
Sun Jan 6 18:53:17 CET 2013


ffmpeg | branch: master | Carl Eugen Hoyos <cehoyos at ag.or.at> | Sun Jan  6 18:48:51 2013 +0100| [1ae9d2820e1181a1109c230d4f1e717443dcce2d] | committer: Carl Eugen Hoyos

Support decoding AC-3 in wav.

All known samples are actually ac3-in-spdif-in-wav, so use
the spdif demuxer to get the ac3 frames.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1ae9d2820e1181a1109c230d4f1e717443dcce2d
---

 libavformat/spdif.h    |    3 +++
 libavformat/spdifdec.c |   23 ++++++++++++++---------
 libavformat/version.h  |    2 +-
 libavformat/wavdec.c   |   17 +++++++++++++++++
 4 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/libavformat/spdif.h b/libavformat/spdif.h
index 4b11de2..0a0d962 100644
--- a/libavformat/spdif.h
+++ b/libavformat/spdif.h
@@ -23,6 +23,7 @@
 #define AVFORMAT_SPDIF_H
 
 #include <stdint.h>
+#include "avformat.h"
 
 #define SYNCWORD1 0xF872
 #define SYNCWORD2 0x4E1F
@@ -58,5 +59,7 @@ static const uint16_t spdif_mpeg_pkt_offset[2][3] = {
 };
 
 void ff_spdif_bswap_buf16(uint16_t *dst, const uint16_t *src, int w);
+int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt);
+int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec);
 
 #endif /* AVFORMAT_SPDIF_H */
diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c
index 94cfe84..e1329cc 100644
--- a/libavformat/spdifdec.c
+++ b/libavformat/spdifdec.c
@@ -105,14 +105,19 @@ static int spdif_get_offset_and_codec(AVFormatContext *s,
 
 static int spdif_probe(AVProbeData *p)
 {
-    const uint8_t *buf = p->buf;
-    const uint8_t *probe_end = p->buf + FFMIN(2 * SPDIF_MAX_OFFSET, p->buf_size - 1);
+    enum AVCodecID codec;
+    return ff_spdif_probe (p->buf, p->buf_size, &codec);
+}
+
+int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec)
+{
+    const uint8_t *buf = p_buf;
+    const uint8_t *probe_end = p_buf + FFMIN(2 * SPDIF_MAX_OFFSET, buf_size - 1);
     const uint8_t *expected_code = buf + 7;
     uint32_t state = 0;
     int sync_codes = 0;
     int consecutive_codes = 0;
     int offset;
-    enum AVCodecID codec;
 
     for (; buf < probe_end; buf++) {
         state = (state << 8) | *buf;
@@ -127,16 +132,16 @@ static int spdif_probe(AVProbeData *p)
             } else
                 consecutive_codes = 0;
 
-            if (buf + 4 + AAC_ADTS_HEADER_SIZE > p->buf + p->buf_size)
+            if (buf + 4 + AAC_ADTS_HEADER_SIZE > p_buf + buf_size)
                 break;
 
             /* continue probing to find more sync codes */
-            probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p->buf + p->buf_size - 1);
+            probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p_buf + buf_size - 1);
 
             /* skip directly to the next sync code */
             if (!spdif_get_offset_and_codec(NULL, (buf[2] << 8) | buf[1],
-                                            &buf[5], &offset, &codec)) {
-                if (buf + offset >= p->buf + p->buf_size)
+                                            &buf[5], &offset, codec)) {
+                if (buf + offset >= p_buf + buf_size)
                     break;
                 expected_code = buf + offset;
                 buf = expected_code - 7;
@@ -161,7 +166,7 @@ static int spdif_read_header(AVFormatContext *s)
     return 0;
 }
 
-static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
+int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     AVIOContext *pb = s->pb;
     enum IEC61937DataType data_type;
@@ -230,6 +235,6 @@ AVInputFormat ff_spdif_demuxer = {
     .long_name      = NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"),
     .read_probe     = spdif_probe,
     .read_header    = spdif_read_header,
-    .read_packet    = spdif_read_packet,
+    .read_packet    = ff_spdif_read_packet,
     .flags          = AVFMT_GENERIC_INDEX,
 };
diff --git a/libavformat/version.h b/libavformat/version.h
index f6901dd..49cd01a 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
 
 #define LIBAVFORMAT_VERSION_MAJOR 54
 #define LIBAVFORMAT_VERSION_MINOR 59
-#define LIBAVFORMAT_VERSION_MICRO 105
+#define LIBAVFORMAT_VERSION_MICRO 106
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index f8a36e9..4511877 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -36,6 +36,7 @@
 #include "w64.h"
 #include "avio.h"
 #include "metadata.h"
+#include "spdif.h"
 
 typedef struct WAVDemuxContext {
     const AVClass *class;
@@ -49,6 +50,7 @@ typedef struct WAVDemuxContext {
     int smv_eof;
     int audio_eof;
     int ignore_length;
+    int spdif;
 } WAVDemuxContext;
 
 
@@ -407,6 +409,21 @@ static int wav_read_packet(AVFormatContext *s,
     AVStream *st;
     WAVDemuxContext *wav = s->priv_data;
 
+    if (CONFIG_SPDIF_DEMUXER && wav->spdif == 0 &&
+        s->streams[0]->codec->codec_tag == 1) {
+        enum AVCodecID codec;
+        ret = ff_spdif_probe(s->pb->buffer, s->pb->buf_end - s->pb->buffer,
+                             &codec);
+        if (ret > AVPROBE_SCORE_MAX / 2) {
+            s->streams[0]->codec->codec_id = codec;
+            wav->spdif = 1;
+        } else {
+            wav->spdif = -1;
+        }
+    }
+    if (CONFIG_SPDIF_DEMUXER && wav->spdif == 1)
+        return ff_spdif_read_packet(s, pkt);
+
     if (wav->smv_data_ofs > 0) {
         int64_t audio_dts, video_dts;
 smv_retry:



More information about the ffmpeg-cvslog mailing list