mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
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.
This commit is contained in:
parent
9ff92cf195
commit
1ae9d2820e
@ -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 */
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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, \
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user