diff options
author | Carl Eugen Hoyos | 2013-01-06 18:48:51 +0100 |
---|---|---|
committer | Carl Eugen Hoyos | 2013-01-06 18:48:51 +0100 |
commit | 1ae9d2820e1181a1109c230d4f1e717443dcce2d (patch) | |
tree | f84cc0408b71350c81dbb784eb8c94cab1756006 | |
parent | 9ff92cf1953d90e0e4f87f76f3f2f6439205a139 (diff) |
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.
-rw-r--r-- | libavformat/spdif.h | 3 | ||||
-rw-r--r-- | libavformat/spdifdec.c | 23 | ||||
-rw-r--r-- | libavformat/version.h | 2 | ||||
-rw-r--r-- | libavformat/wavdec.c | 17 |
4 files changed, 35 insertions, 10 deletions
diff --git a/libavformat/spdif.h b/libavformat/spdif.h index 4b11de20d1..0a0d962ba4 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 94cfe8443d..e1329cc6d3 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 f6901dd8f1..49cd01a9d8 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 f8a36e9d6c..451187739f 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: |