[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