X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmpeg.c;h=8ae4740920b8a9c3a6c204502b4a47de231af928;hb=8ea8be595166cdae73bf3f8bee2f28bc94f1c988;hp=abdc6a937cb9ebed02ebc4b1dcbd5d91b991f0f8;hpb=d0f098a5e0bae84d98eb48ea5ba173422e004fe3;p=ffmpeg diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index abdc6a937cb..8ae4740920b 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -20,6 +20,7 @@ */ #include "avformat.h" +#include "avio_internal.h" #include "internal.h" #include "mpeg.h" @@ -128,6 +129,7 @@ typedef struct MpegDemuxContext { int sofdec; int dvd; int imkh_cctv; + int raw_ac3; #if CONFIG_VOBSUB_DEMUXER AVFormatContext *sub_ctx; FFDemuxSubtitlesQueue q[32]; @@ -442,8 +444,24 @@ redo: } if (startcode == PRIVATE_STREAM_1) { + int ret = ffio_ensure_seekback(s->pb, 2); + + if (ret < 0) + return ret; + startcode = avio_r8(s->pb); - len--; + m->raw_ac3 = 0; + if (startcode == 0x0b) { + if (avio_r8(s->pb) == 0x77) { + startcode = 0x80; + m->raw_ac3 = 1; + avio_skip(s->pb, -2); + } else { + avio_skip(s->pb, -1); + } + } else { + len--; + } } if (len < 0) goto error_redo; @@ -486,14 +504,16 @@ redo: if (len < 4) goto skip; - /* audio: skip header */ - avio_r8(s->pb); - lpcm_header_len = avio_rb16(s->pb); - len -= 3; - if (startcode >= 0xb0 && startcode <= 0xbf) { - /* MLP/TrueHD audio has a 4-byte header */ + if (!m->raw_ac3) { + /* audio: skip header */ avio_r8(s->pb); - len--; + lpcm_header_len = avio_rb16(s->pb); + len -= 3; + if (startcode >= 0xb0 && startcode <= 0xbf) { + /* MLP/TrueHD audio has a 4-byte header */ + avio_r8(s->pb); + len--; + } } } @@ -568,7 +588,7 @@ redo: codec_id = AV_CODEC_ID_DTS; } else if (startcode >= 0xa0 && startcode <= 0xaf) { type = AVMEDIA_TYPE_AUDIO; - if (lpcm_header_len == 6 || startcode == 0xa1) { + if (lpcm_header_len >= 6 && startcode == 0xa1) { codec_id = AV_CODEC_ID_MLP; } else { codec_id = AV_CODEC_ID_PCM_DVD;