Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/mpeg.c')
-rw-r--r--libavformat/mpeg.c93
1 files changed, 47 insertions, 46 deletions
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 2d08b17682..22e7869961 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -2,20 +2,20 @@
* MPEG1/2 demuxer
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -74,6 +74,7 @@ static int mpegps_probe(AVProbeData *p)
// and audio streams
else if((code & 0xe0) == AUDIO_ID && pes) {audio++; i+=len;}
else if(code == PRIVATE_STREAM_1 && pes) {priv1++; i+=len;}
+ else if(code == 0x1fd && pes) vid++; //VC1
else if((code & 0xf0) == VIDEO_ID && !pes) invalid++;
else if((code & 0xe0) == AUDIO_ID && !pes) invalid++;
@@ -81,18 +82,19 @@ static int mpegps_probe(AVProbeData *p)
}
}
- if(vid+audio > invalid) /* invalid VDR files nd short PES streams */
+ if(vid+audio > invalid+1) /* invalid VDR files nd short PES streams */
score= AVPROBE_SCORE_MAX/4;
if(sys>invalid && sys*9 <= pspack*10)
- return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+ return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9)
return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */
- return (audio > 12 || vid > 3) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4;
+ return (audio > 12 || vid > 3 + 2*invalid) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4;
//02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
//mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
+ //Have\ Yourself\ a\ Merry\ Little\ Christmas.mp3 0 0 0 5 0 1 len:21618
return score;
}
@@ -108,6 +110,7 @@ static int mpegps_read_header(AVFormatContext *s)
MpegDemuxContext *m = s->priv_data;
const char *sofdec = "Sofdec";
int v, i = 0;
+ int64_t last_pos = avio_tell(s->pb);
m->header_state = 0xff;
s->ctx_flags |= AVFMTCTX_NOHEADER;
@@ -115,12 +118,14 @@ static int mpegps_read_header(AVFormatContext *s)
m->sofdec = -1;
do {
v = avio_r8(s->pb);
- m->header_state = m->header_state << 8 | v;
m->sofdec++;
} while (v == sofdec[i] && i++ < 6);
m->sofdec = (m->sofdec == 6) ? 1 : 0;
+ if (!m->sofdec)
+ avio_seek(s->pb, last_pos, SEEK_SET);
+
/* no need to do more */
return 0;
}
@@ -144,7 +149,7 @@ static int find_next_start_code(AVIOContext *pb, int *size_ptr,
state = *header_state;
n = *size_ptr;
while (n > 0) {
- if (pb->eof_reached)
+ if (url_feof(pb))
break;
v = avio_r8(pb);
n--;
@@ -218,7 +223,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
startcode = find_next_start_code(s->pb, &size, &m->header_state);
last_sync = avio_tell(s->pb);
if (startcode < 0){
- if(s->pb->eof_reached)
+ if(url_feof(s->pb))
return AVERROR_EOF;
//FIXME we should remember header_state
return AVERROR(EAGAIN);
@@ -339,21 +344,9 @@ static int mpegps_read_pes_header(AVFormatContext *s,
else if( c!= 0xf )
goto redo;
- if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) {
+ if (startcode == PRIVATE_STREAM_1) {
startcode = avio_r8(s->pb);
len--;
- if (startcode >= 0x80 && startcode <= 0xcf) {
- /* audio: skip header */
- avio_r8(s->pb);
- avio_r8(s->pb);
- avio_r8(s->pb);
- len -= 3;
- if (startcode >= 0xb0 && startcode <= 0xbf) {
- /* MLP/TrueHD audio has a 4-byte header */
- avio_r8(s->pb);
- len--;
- }
- }
}
if(len<0)
goto error_redo;
@@ -380,20 +373,30 @@ static int mpegps_read_packet(AVFormatContext *s,
MpegDemuxContext *m = s->priv_data;
AVStream *st;
int len, startcode, i, es_type, ret;
+ int lpcm_header_len;
+ int request_probe= 0;
enum AVCodecID codec_id = AV_CODEC_ID_NONE;
enum AVMediaType type;
int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
- uint8_t av_uninit(dvdaudio_substream_type);
redo:
len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts);
if (len < 0)
return len;
- if(startcode == 0x1bd) {
- dvdaudio_substream_type = avio_r8(s->pb);
- avio_skip(s->pb, 3);
- len -= 4;
+ if (startcode >= 0x80 && startcode <= 0xcf) {
+ 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 */
+ avio_r8(s->pb);
+ len--;
+ }
}
/* now find stream */
@@ -438,7 +441,7 @@ static int mpegps_read_packet(AVFormatContext *s,
if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
codec_id = AV_CODEC_ID_CAVS;
else
- codec_id = AV_CODEC_ID_PROBE;
+ request_probe= 1;
type = AVMEDIA_TYPE_VIDEO;
} else if (startcode >= 0x1c0 && startcode <= 0x1df) {
type = AVMEDIA_TYPE_AUDIO;
@@ -453,8 +456,12 @@ static int mpegps_read_packet(AVFormatContext *s,
codec_id = AV_CODEC_ID_DTS;
} else if (startcode >= 0xa0 && startcode <= 0xaf) {
type = AVMEDIA_TYPE_AUDIO;
- /* 16 bit form will be handled as AV_CODEC_ID_PCM_S16BE */
- codec_id = AV_CODEC_ID_PCM_DVD;
+ if(lpcm_header_len == 6) {
+ codec_id = AV_CODEC_ID_MLP;
+ } else {
+ /* 16 bit form will be handled as AV_CODEC_ID_PCM_S16BE */
+ codec_id = AV_CODEC_ID_PCM_DVD;
+ }
} else if (startcode >= 0xb0 && startcode <= 0xbf) {
type = AVMEDIA_TYPE_AUDIO;
codec_id = AV_CODEC_ID_TRUEHD;
@@ -468,19 +475,6 @@ static int mpegps_read_packet(AVFormatContext *s,
} else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
type = AVMEDIA_TYPE_VIDEO;
codec_id = AV_CODEC_ID_VC1;
- } else if (startcode == 0x1bd) {
- // check dvd audio substream type
- type = AVMEDIA_TYPE_AUDIO;
- switch(dvdaudio_substream_type & 0xe0) {
- case 0xa0: codec_id = AV_CODEC_ID_PCM_DVD;
- break;
- case 0x80: if((dvdaudio_substream_type & 0xf8) == 0x88)
- codec_id = AV_CODEC_ID_DTS;
- else codec_id = AV_CODEC_ID_AC3;
- break;
- default: av_log(s, AV_LOG_ERROR, "Unknown 0x1bd sub-stream\n");
- goto skip;
- }
} else {
skip:
/* skip packet */
@@ -494,13 +488,19 @@ static int mpegps_read_packet(AVFormatContext *s,
st->id = startcode;
st->codec->codec_type = type;
st->codec->codec_id = codec_id;
+ st->request_probe = request_probe;
if (codec_id != AV_CODEC_ID_PCM_S16BE)
st->need_parsing = AVSTREAM_PARSE_FULL;
found:
if(st->discard >= AVDISCARD_ALL)
goto skip;
- if ((startcode >= 0xa0 && startcode <= 0xaf) ||
- (startcode == 0x1bd && ((dvdaudio_substream_type & 0xe0) == 0xa0))) {
+ if (startcode >= 0xa0 && startcode <= 0xaf) {
+ if (lpcm_header_len == 6) {
+ if (len < 6)
+ goto skip;
+ avio_skip(s->pb, 6);
+ len -=6;
+ } else {
int b1, freq;
/* for LPCM, we just skip the header and consider it is raw
@@ -522,6 +522,7 @@ static int mpegps_read_packet(AVFormatContext *s,
st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
else if (st->codec->bits_per_coded_sample == 28)
return AVERROR(EINVAL);
+ }
}
ret = av_get_packet(s->pb, pkt, len);
pkt->pts = pts;