Libav
|
00001 /* 00002 * MPEG1/2 demuxer 00003 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "avformat.h" 00023 #include "mpeg.h" 00024 00025 //#define DEBUG_SEEK 00026 00027 #undef NDEBUG 00028 #include <assert.h> 00029 00030 /*********************************************/ 00031 /* demux code */ 00032 00033 #define MAX_SYNC_SIZE 100000 00034 00035 static int check_pes(uint8_t *p, uint8_t *end){ 00036 int pes1; 00037 int pes2= (p[3] & 0xC0) == 0x80 00038 && (p[4] & 0xC0) != 0x40 00039 &&((p[4] & 0xC0) == 0x00 || (p[4]&0xC0)>>2 == (p[6]&0xF0)); 00040 00041 for(p+=3; p<end && *p == 0xFF; p++); 00042 if((*p&0xC0) == 0x40) p+=2; 00043 if((*p&0xF0) == 0x20){ 00044 pes1= p[0]&p[2]&p[4]&1; 00045 }else if((*p&0xF0) == 0x30){ 00046 pes1= p[0]&p[2]&p[4]&p[5]&p[7]&p[9]&1; 00047 }else 00048 pes1 = *p == 0x0F; 00049 00050 return pes1||pes2; 00051 } 00052 00053 static int mpegps_probe(AVProbeData *p) 00054 { 00055 uint32_t code= -1; 00056 int sys=0, pspack=0, priv1=0, vid=0, audio=0, invalid=0; 00057 int i; 00058 int score=0; 00059 00060 for(i=0; i<p->buf_size; i++){ 00061 code = (code<<8) + p->buf[i]; 00062 if ((code & 0xffffff00) == 0x100) { 00063 int pes= check_pes(p->buf+i, p->buf+p->buf_size); 00064 00065 if(code == SYSTEM_HEADER_START_CODE) sys++; 00066 else if(code == PRIVATE_STREAM_1) priv1++; 00067 else if(code == PACK_START_CODE) pspack++; 00068 else if((code & 0xf0) == VIDEO_ID && pes) vid++; 00069 else if((code & 0xe0) == AUDIO_ID && pes) audio++; 00070 00071 else if((code & 0xf0) == VIDEO_ID && !pes) invalid++; 00072 else if((code & 0xe0) == AUDIO_ID && !pes) invalid++; 00073 } 00074 } 00075 00076 if(vid+audio > invalid) /* invalid VDR files nd short PES streams */ 00077 score= AVPROBE_SCORE_MAX/4; 00078 00079 //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d %d len:%d\n", sys, priv1, pspack,vid, audio, invalid, p->buf_size); 00080 if(sys>invalid && sys*9 <= pspack*10) 00081 return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg 00082 if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9) 00083 return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg 00084 if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */ 00085 return (audio > 12 || vid > 3) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; 00086 00087 //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1 00088 //mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6 00089 return score; 00090 } 00091 00092 00093 typedef struct MpegDemuxContext { 00094 int32_t header_state; 00095 unsigned char psm_es_type[256]; 00096 int sofdec; 00097 } MpegDemuxContext; 00098 00099 static int mpegps_read_header(AVFormatContext *s, 00100 AVFormatParameters *ap) 00101 { 00102 MpegDemuxContext *m = s->priv_data; 00103 const char *sofdec = "Sofdec"; 00104 int v, i = 0; 00105 00106 m->header_state = 0xff; 00107 s->ctx_flags |= AVFMTCTX_NOHEADER; 00108 00109 m->sofdec = -1; 00110 do { 00111 v = get_byte(s->pb); 00112 m->header_state = m->header_state << 8 | v; 00113 m->sofdec++; 00114 } while (v == sofdec[i] && i++ < 6); 00115 00116 m->sofdec = (m->sofdec == 6) ? 1 : 0; 00117 00118 /* no need to do more */ 00119 return 0; 00120 } 00121 00122 static int64_t get_pts(ByteIOContext *pb, int c) 00123 { 00124 uint8_t buf[5]; 00125 00126 buf[0] = c<0 ? get_byte(pb) : c; 00127 get_buffer(pb, buf+1, 4); 00128 00129 return ff_parse_pes_pts(buf); 00130 } 00131 00132 static int find_next_start_code(ByteIOContext *pb, int *size_ptr, 00133 int32_t *header_state) 00134 { 00135 unsigned int state, v; 00136 int val, n; 00137 00138 state = *header_state; 00139 n = *size_ptr; 00140 while (n > 0) { 00141 if (url_feof(pb)) 00142 break; 00143 v = get_byte(pb); 00144 n--; 00145 if (state == 0x000001) { 00146 state = ((state << 8) | v) & 0xffffff; 00147 val = state; 00148 goto found; 00149 } 00150 state = ((state << 8) | v) & 0xffffff; 00151 } 00152 val = -1; 00153 found: 00154 *header_state = state; 00155 *size_ptr = n; 00156 return val; 00157 } 00158 00159 #if 0 /* unused, remove? */ 00160 /* XXX: optimize */ 00161 static int find_prev_start_code(ByteIOContext *pb, int *size_ptr) 00162 { 00163 int64_t pos, pos_start; 00164 int max_size, start_code; 00165 00166 max_size = *size_ptr; 00167 pos_start = url_ftell(pb); 00168 00169 /* in order to go faster, we fill the buffer */ 00170 pos = pos_start - 16386; 00171 if (pos < 0) 00172 pos = 0; 00173 url_fseek(pb, pos, SEEK_SET); 00174 get_byte(pb); 00175 00176 pos = pos_start; 00177 for(;;) { 00178 pos--; 00179 if (pos < 0 || (pos_start - pos) >= max_size) { 00180 start_code = -1; 00181 goto the_end; 00182 } 00183 url_fseek(pb, pos, SEEK_SET); 00184 start_code = get_be32(pb); 00185 if ((start_code & 0xffffff00) == 0x100) 00186 break; 00187 } 00188 the_end: 00189 *size_ptr = pos_start - pos; 00190 return start_code; 00191 } 00192 #endif 00193 00200 static long mpegps_psm_parse(MpegDemuxContext *m, ByteIOContext *pb) 00201 { 00202 int psm_length, ps_info_length, es_map_length; 00203 00204 psm_length = get_be16(pb); 00205 get_byte(pb); 00206 get_byte(pb); 00207 ps_info_length = get_be16(pb); 00208 00209 /* skip program_stream_info */ 00210 url_fskip(pb, ps_info_length); 00211 es_map_length = get_be16(pb); 00212 00213 /* at least one es available? */ 00214 while (es_map_length >= 4){ 00215 unsigned char type = get_byte(pb); 00216 unsigned char es_id = get_byte(pb); 00217 uint16_t es_info_length = get_be16(pb); 00218 /* remember mapping from stream id to stream type */ 00219 m->psm_es_type[es_id] = type; 00220 /* skip program_stream_info */ 00221 url_fskip(pb, es_info_length); 00222 es_map_length -= 4 + es_info_length; 00223 } 00224 get_be32(pb); /* crc32 */ 00225 return 2 + psm_length; 00226 } 00227 00228 /* read the next PES header. Return its position in ppos 00229 (if not NULL), and its start code, pts and dts. 00230 */ 00231 static int mpegps_read_pes_header(AVFormatContext *s, 00232 int64_t *ppos, int *pstart_code, 00233 int64_t *ppts, int64_t *pdts) 00234 { 00235 MpegDemuxContext *m = s->priv_data; 00236 int len, size, startcode, c, flags, header_len; 00237 int pes_ext, ext2_len, id_ext, skip; 00238 int64_t pts, dts; 00239 int64_t last_sync= url_ftell(s->pb); 00240 00241 error_redo: 00242 url_fseek(s->pb, last_sync, SEEK_SET); 00243 redo: 00244 /* next start code (should be immediately after) */ 00245 m->header_state = 0xff; 00246 size = MAX_SYNC_SIZE; 00247 startcode = find_next_start_code(s->pb, &size, &m->header_state); 00248 last_sync = url_ftell(s->pb); 00249 //printf("startcode=%x pos=0x%"PRIx64"\n", startcode, url_ftell(s->pb)); 00250 if (startcode < 0){ 00251 if(url_feof(s->pb)) 00252 return AVERROR_EOF; 00253 //FIXME we should remember header_state 00254 return AVERROR(EAGAIN); 00255 } 00256 00257 if (startcode == PACK_START_CODE) 00258 goto redo; 00259 if (startcode == SYSTEM_HEADER_START_CODE) 00260 goto redo; 00261 if (startcode == PADDING_STREAM) { 00262 url_fskip(s->pb, get_be16(s->pb)); 00263 goto redo; 00264 } 00265 if (startcode == PRIVATE_STREAM_2) { 00266 len = get_be16(s->pb); 00267 if (!m->sofdec) { 00268 while (len-- >= 6) { 00269 if (get_byte(s->pb) == 'S') { 00270 uint8_t buf[5]; 00271 get_buffer(s->pb, buf, sizeof(buf)); 00272 m->sofdec = !memcmp(buf, "ofdec", 5); 00273 len -= sizeof(buf); 00274 break; 00275 } 00276 } 00277 m->sofdec -= !m->sofdec; 00278 } 00279 url_fskip(s->pb, len); 00280 goto redo; 00281 } 00282 if (startcode == PROGRAM_STREAM_MAP) { 00283 mpegps_psm_parse(m, s->pb); 00284 goto redo; 00285 } 00286 00287 /* find matching stream */ 00288 if (!((startcode >= 0x1c0 && startcode <= 0x1df) || 00289 (startcode >= 0x1e0 && startcode <= 0x1ef) || 00290 (startcode == 0x1bd) || (startcode == 0x1fd))) 00291 goto redo; 00292 if (ppos) { 00293 *ppos = url_ftell(s->pb) - 4; 00294 } 00295 len = get_be16(s->pb); 00296 pts = 00297 dts = AV_NOPTS_VALUE; 00298 /* stuffing */ 00299 for(;;) { 00300 if (len < 1) 00301 goto error_redo; 00302 c = get_byte(s->pb); 00303 len--; 00304 /* XXX: for mpeg1, should test only bit 7 */ 00305 if (c != 0xff) 00306 break; 00307 } 00308 if ((c & 0xc0) == 0x40) { 00309 /* buffer scale & size */ 00310 get_byte(s->pb); 00311 c = get_byte(s->pb); 00312 len -= 2; 00313 } 00314 if ((c & 0xe0) == 0x20) { 00315 dts = pts = get_pts(s->pb, c); 00316 len -= 4; 00317 if (c & 0x10){ 00318 dts = get_pts(s->pb, -1); 00319 len -= 5; 00320 } 00321 } else if ((c & 0xc0) == 0x80) { 00322 /* mpeg 2 PES */ 00323 #if 0 /* some streams have this field set for no apparent reason */ 00324 if ((c & 0x30) != 0) { 00325 /* Encrypted multiplex not handled */ 00326 goto redo; 00327 } 00328 #endif 00329 flags = get_byte(s->pb); 00330 header_len = get_byte(s->pb); 00331 len -= 2; 00332 if (header_len > len) 00333 goto error_redo; 00334 len -= header_len; 00335 if (flags & 0x80) { 00336 dts = pts = get_pts(s->pb, -1); 00337 header_len -= 5; 00338 if (flags & 0x40) { 00339 dts = get_pts(s->pb, -1); 00340 header_len -= 5; 00341 } 00342 } 00343 if (flags & 0x3f && header_len == 0){ 00344 flags &= 0xC0; 00345 av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n"); 00346 } 00347 if (flags & 0x01) { /* PES extension */ 00348 pes_ext = get_byte(s->pb); 00349 header_len--; 00350 /* Skip PES private data, program packet sequence counter and P-STD buffer */ 00351 skip = (pes_ext >> 4) & 0xb; 00352 skip += skip & 0x9; 00353 if (pes_ext & 0x40 || skip > header_len){ 00354 av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext); 00355 pes_ext=skip=0; 00356 } 00357 url_fskip(s->pb, skip); 00358 header_len -= skip; 00359 00360 if (pes_ext & 0x01) { /* PES extension 2 */ 00361 ext2_len = get_byte(s->pb); 00362 header_len--; 00363 if ((ext2_len & 0x7f) > 0) { 00364 id_ext = get_byte(s->pb); 00365 if ((id_ext & 0x80) == 0) 00366 startcode = ((startcode & 0xff) << 8) | id_ext; 00367 header_len--; 00368 } 00369 } 00370 } 00371 if(header_len < 0) 00372 goto error_redo; 00373 url_fskip(s->pb, header_len); 00374 } 00375 else if( c!= 0xf ) 00376 goto redo; 00377 00378 if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) { 00379 startcode = get_byte(s->pb); 00380 len--; 00381 if (startcode >= 0x80 && startcode <= 0xcf) { 00382 /* audio: skip header */ 00383 get_byte(s->pb); 00384 get_byte(s->pb); 00385 get_byte(s->pb); 00386 len -= 3; 00387 if (startcode >= 0xb0 && startcode <= 0xbf) { 00388 /* MLP/TrueHD audio has a 4-byte header */ 00389 get_byte(s->pb); 00390 len--; 00391 } 00392 } 00393 } 00394 if(len<0) 00395 goto error_redo; 00396 if(dts != AV_NOPTS_VALUE && ppos){ 00397 int i; 00398 for(i=0; i<s->nb_streams; i++){ 00399 if(startcode == s->streams[i]->id && 00400 !url_is_streamed(s->pb) /* index useless on streams anyway */) { 00401 ff_reduce_index(s, i); 00402 av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); 00403 } 00404 } 00405 } 00406 00407 *pstart_code = startcode; 00408 *ppts = pts; 00409 *pdts = dts; 00410 return len; 00411 } 00412 00413 static int mpegps_read_packet(AVFormatContext *s, 00414 AVPacket *pkt) 00415 { 00416 MpegDemuxContext *m = s->priv_data; 00417 AVStream *st; 00418 int len, startcode, i, es_type; 00419 enum CodecID codec_id = CODEC_ID_NONE; 00420 enum AVMediaType type; 00421 int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work 00422 uint8_t av_uninit(dvdaudio_substream_type); 00423 00424 redo: 00425 len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts); 00426 if (len < 0) 00427 return len; 00428 00429 if(startcode == 0x1bd) { 00430 dvdaudio_substream_type = get_byte(s->pb); 00431 url_fskip(s->pb, 3); 00432 len -= 4; 00433 } 00434 00435 /* now find stream */ 00436 for(i=0;i<s->nb_streams;i++) { 00437 st = s->streams[i]; 00438 if (st->id == startcode) 00439 goto found; 00440 } 00441 00442 es_type = m->psm_es_type[startcode & 0xff]; 00443 if(es_type > 0 && es_type != STREAM_TYPE_PRIVATE_DATA){ 00444 if(es_type == STREAM_TYPE_VIDEO_MPEG1){ 00445 codec_id = CODEC_ID_MPEG2VIDEO; 00446 type = AVMEDIA_TYPE_VIDEO; 00447 } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){ 00448 codec_id = CODEC_ID_MPEG2VIDEO; 00449 type = AVMEDIA_TYPE_VIDEO; 00450 } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 || 00451 es_type == STREAM_TYPE_AUDIO_MPEG2){ 00452 codec_id = CODEC_ID_MP3; 00453 type = AVMEDIA_TYPE_AUDIO; 00454 } else if(es_type == STREAM_TYPE_AUDIO_AAC){ 00455 codec_id = CODEC_ID_AAC; 00456 type = AVMEDIA_TYPE_AUDIO; 00457 } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){ 00458 codec_id = CODEC_ID_MPEG4; 00459 type = AVMEDIA_TYPE_VIDEO; 00460 } else if(es_type == STREAM_TYPE_VIDEO_H264){ 00461 codec_id = CODEC_ID_H264; 00462 type = AVMEDIA_TYPE_VIDEO; 00463 } else if(es_type == STREAM_TYPE_AUDIO_AC3){ 00464 codec_id = CODEC_ID_AC3; 00465 type = AVMEDIA_TYPE_AUDIO; 00466 } else { 00467 goto skip; 00468 } 00469 } else if (startcode >= 0x1e0 && startcode <= 0x1ef) { 00470 static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 }; 00471 unsigned char buf[8]; 00472 get_buffer(s->pb, buf, 8); 00473 url_fseek(s->pb, -8, SEEK_CUR); 00474 if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1)) 00475 codec_id = CODEC_ID_CAVS; 00476 else 00477 codec_id = CODEC_ID_PROBE; 00478 type = AVMEDIA_TYPE_VIDEO; 00479 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { 00480 type = AVMEDIA_TYPE_AUDIO; 00481 codec_id = m->sofdec > 0 ? CODEC_ID_ADPCM_ADX : CODEC_ID_MP2; 00482 } else if (startcode >= 0x80 && startcode <= 0x87) { 00483 type = AVMEDIA_TYPE_AUDIO; 00484 codec_id = CODEC_ID_AC3; 00485 } else if ( ( startcode >= 0x88 && startcode <= 0x8f) 00486 ||( startcode >= 0x98 && startcode <= 0x9f)) { 00487 /* 0x90 - 0x97 is reserved for SDDS in DVD specs */ 00488 type = AVMEDIA_TYPE_AUDIO; 00489 codec_id = CODEC_ID_DTS; 00490 } else if (startcode >= 0xa0 && startcode <= 0xaf) { 00491 type = AVMEDIA_TYPE_AUDIO; 00492 /* 16 bit form will be handled as CODEC_ID_PCM_S16BE */ 00493 codec_id = CODEC_ID_PCM_DVD; 00494 } else if (startcode >= 0xb0 && startcode <= 0xbf) { 00495 type = AVMEDIA_TYPE_AUDIO; 00496 codec_id = CODEC_ID_TRUEHD; 00497 } else if (startcode >= 0xc0 && startcode <= 0xcf) { 00498 /* Used for both AC-3 and E-AC-3 in EVOB files */ 00499 type = AVMEDIA_TYPE_AUDIO; 00500 codec_id = CODEC_ID_AC3; 00501 } else if (startcode >= 0x20 && startcode <= 0x3f) { 00502 type = AVMEDIA_TYPE_SUBTITLE; 00503 codec_id = CODEC_ID_DVD_SUBTITLE; 00504 } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) { 00505 type = AVMEDIA_TYPE_VIDEO; 00506 codec_id = CODEC_ID_VC1; 00507 } else if (startcode == 0x1bd) { 00508 // check dvd audio substream type 00509 type = AVMEDIA_TYPE_AUDIO; 00510 switch(dvdaudio_substream_type & 0xe0) { 00511 case 0xa0: codec_id = CODEC_ID_PCM_DVD; 00512 break; 00513 case 0x80: if((dvdaudio_substream_type & 0xf8) == 0x88) 00514 codec_id = CODEC_ID_DTS; 00515 else codec_id = CODEC_ID_AC3; 00516 break; 00517 default: av_log(s, AV_LOG_ERROR, "Unknown 0x1bd sub-stream\n"); 00518 goto skip; 00519 } 00520 } else { 00521 skip: 00522 /* skip packet */ 00523 url_fskip(s->pb, len); 00524 goto redo; 00525 } 00526 /* no stream found: add a new stream */ 00527 st = av_new_stream(s, startcode); 00528 if (!st) 00529 goto skip; 00530 st->codec->codec_type = type; 00531 st->codec->codec_id = codec_id; 00532 if (codec_id != CODEC_ID_PCM_S16BE) 00533 st->need_parsing = AVSTREAM_PARSE_FULL; 00534 found: 00535 if(st->discard >= AVDISCARD_ALL) 00536 goto skip; 00537 if ((startcode >= 0xa0 && startcode <= 0xaf) || 00538 (startcode == 0x1bd && ((dvdaudio_substream_type & 0xe0) == 0xa0))) { 00539 int b1, freq; 00540 00541 /* for LPCM, we just skip the header and consider it is raw 00542 audio data */ 00543 if (len <= 3) 00544 goto skip; 00545 get_byte(s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ 00546 b1 = get_byte(s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ 00547 get_byte(s->pb); /* dynamic range control (0x80 = off) */ 00548 len -= 3; 00549 freq = (b1 >> 4) & 3; 00550 st->codec->sample_rate = lpcm_freq_tab[freq]; 00551 st->codec->channels = 1 + (b1 & 7); 00552 st->codec->bits_per_coded_sample = 16 + ((b1 >> 6) & 3) * 4; 00553 st->codec->bit_rate = st->codec->channels * 00554 st->codec->sample_rate * 00555 st->codec->bits_per_coded_sample; 00556 if (st->codec->bits_per_coded_sample == 16) 00557 st->codec->codec_id = CODEC_ID_PCM_S16BE; 00558 else if (st->codec->bits_per_coded_sample == 28) 00559 return AVERROR(EINVAL); 00560 } 00561 av_new_packet(pkt, len); 00562 get_buffer(s->pb, pkt->data, pkt->size); 00563 pkt->pts = pts; 00564 pkt->dts = dts; 00565 pkt->pos = dummy_pos; 00566 pkt->stream_index = st->index; 00567 #if 0 00568 av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n", 00569 pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size); 00570 #endif 00571 00572 return 0; 00573 } 00574 00575 static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, 00576 int64_t *ppos, int64_t pos_limit) 00577 { 00578 int len, startcode; 00579 int64_t pos, pts, dts; 00580 00581 pos = *ppos; 00582 #ifdef DEBUG_SEEK 00583 printf("read_dts: pos=0x%"PRIx64" next=%d -> ", pos, find_next); 00584 #endif 00585 if (url_fseek(s->pb, pos, SEEK_SET) < 0) 00586 return AV_NOPTS_VALUE; 00587 00588 for(;;) { 00589 len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts); 00590 if (len < 0) { 00591 #ifdef DEBUG_SEEK 00592 printf("none (ret=%d)\n", len); 00593 #endif 00594 return AV_NOPTS_VALUE; 00595 } 00596 if (startcode == s->streams[stream_index]->id && 00597 dts != AV_NOPTS_VALUE) { 00598 break; 00599 } 00600 url_fskip(s->pb, len); 00601 } 00602 #ifdef DEBUG_SEEK 00603 printf("pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", pos, dts, dts / 90000.0); 00604 #endif 00605 *ppos = pos; 00606 return dts; 00607 } 00608 00609 AVInputFormat mpegps_demuxer = { 00610 "mpeg", 00611 NULL_IF_CONFIG_SMALL("MPEG-PS format"), 00612 sizeof(MpegDemuxContext), 00613 mpegps_probe, 00614 mpegps_read_header, 00615 mpegps_read_packet, 00616 NULL, 00617 NULL, //mpegps_read_seek, 00618 mpegps_read_dts, 00619 .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT, 00620 };