2 * MPG/VOB file parser for DEMUXER v2.5
3 * copyright (c) 2001 by A'rpi/ESP-team
5 * This file is part of MPlayer.
7 * MPlayer is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * MPlayer is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "libavutil/attributes.h"
32 #include "libmpcodecs/dec_audio.h"
33 #include "stream/stream.h"
39 //#define MAX_PS_PACKETSIZE 2048
40 #define MAX_PS_PACKETSIZE (224*1024)
43 #define VIDEO_MPEG1 0x10000001
44 #define VIDEO_MPEG2 0x10000002
45 #define VIDEO_MPEG4 0x10000004
46 #define VIDEO_H264 0x10000005
47 #define AUDIO_MP2 0x50
48 #define AUDIO_A52 0x2000
49 #define AUDIO_LPCM_BE 0x10001
50 #define AUDIO_AAC mmioFOURCC('M', 'P', '4', 'A')
52 typedef struct mpg_demuxer
{
54 float first_pts
; // first pts found in stream
55 float first_to_final_pts_len
; // difference between final pts and first pts
56 int has_valid_timestamps
; // !=0 iff time stamps look linear
57 // (not necessarily starting with 0)
58 unsigned int es_map
[0x40]; //es map of stream types (associated to the pes id) from 0xb0 to 0xef
60 int a_stream_ids
[MAX_A_STREAMS
];
63 static int mpeg_pts_error
=0;
66 static int parse_psm(demuxer_t
*demux
, int len
) {
67 unsigned char c
, id
, type
;
68 unsigned int plen
, prog_len
, es_map_len
;
69 mpg_demuxer_t
*priv
= (mpg_demuxer_t
*) demux
->priv
;
71 mp_dbg(MSGT_DEMUX
,MSGL_V
, "PARSE_PSM, len=%d\n", len
);
72 if(! len
|| len
> 1018)
75 c
= stream_read_char(demux
->stream
);
77 stream_skip(demux
->stream
, len
- 1); //not yet valid, discard
80 stream_skip(demux
->stream
, 1);
81 prog_len
= stream_read_word(demux
->stream
); //length of program descriptors
82 stream_skip(demux
->stream
, prog_len
); //.. that we ignore
83 es_map_len
= stream_read_word(demux
->stream
); //length of elementary streams map
84 es_map_len
= FFMIN(es_map_len
, len
- prog_len
- 8); //sanity check
85 while(es_map_len
> 0) {
86 type
= stream_read_char(demux
->stream
);
87 id
= stream_read_char(demux
->stream
);
88 if(id
>= 0xB0 && id
<= 0xEF && priv
) {
89 int idoffset
= id
- 0xB0;
92 priv
->es_map
[idoffset
] = VIDEO_MPEG1
;
95 priv
->es_map
[idoffset
] = VIDEO_MPEG2
;
99 priv
->es_map
[idoffset
] = AUDIO_MP2
;
103 priv
->es_map
[idoffset
] = AUDIO_AAC
;
106 priv
->es_map
[idoffset
] = VIDEO_MPEG4
;
109 priv
->es_map
[idoffset
] = VIDEO_H264
;
112 priv
->es_map
[idoffset
] = AUDIO_A52
;
115 mp_dbg(MSGT_DEMUX
,MSGL_V
, "PSM ES, id=0x%x, type=%x, stype: %x\n", id
, type
, priv
->es_map
[idoffset
]);
117 plen
= stream_read_word(demux
->stream
); //length of elementary stream descriptors
118 plen
= FFMIN(plen
, es_map_len
); //sanity check
119 stream_skip(demux
->stream
, plen
); //skip descriptors for now
120 es_map_len
-= 4 + plen
;
122 stream_skip(demux
->stream
, 4); //skip crc32
126 // 500000 is a wild guess
127 #define TIMESTAMP_PROBE_LEN 500000
129 //MAX_PTS_DIFF_FOR_CONSECUTIVE denotes the maximum difference
130 //between two pts to consider them consecutive
131 //1.0 is a wild guess
132 #define MAX_PTS_DIFF_FOR_CONSECUTIVE 1.0
134 //returns the first pts found within TIME_STAMP_PROBE_LEN bytes after stream_pos in demuxer's stream.
135 //if no pts is found or an error occurs, -1.0 is returned.
137 static float read_first_mpeg_pts_at_position(demuxer_t
* demuxer
, off_t stream_pos
)
139 stream_t
*s
= demuxer
->stream
;
140 mpg_demuxer_t
*mpg_d
= demuxer
->priv
;
141 float pts
= -1.0; //the pts to return;
142 float found_pts1
; //the most recently found pts
143 float found_pts2
; //the pts found before found_pts1
144 float found_pts3
; //the pts found before found_pts2
147 if(!mpg_d
|| stream_pos
< 0)
150 found_pts3
= found_pts2
= found_pts1
= mpg_d
->last_pts
;
151 stream_seek(s
, stream_pos
);
154 //However, we do not stop at the first found one, as timestamps may reset
155 //Therefore, we seek until we found three consecutive
156 //pts within MAX_PTS_DIFF_FOR_CONSECUTIVE.
158 while(found
<3 && !s
->eof
159 && (fabsf(found_pts2
-found_pts1
) < MAX_PTS_DIFF_FOR_CONSECUTIVE
)
160 && (fabsf(found_pts3
-found_pts2
) < MAX_PTS_DIFF_FOR_CONSECUTIVE
)
161 && (stream_tell(s
) < stream_pos
+ TIMESTAMP_PROBE_LEN
)
162 && ds_fill_buffer(demuxer
->video
))
164 if(mpg_d
->last_pts
!= found_pts1
)
167 found_pts3
= found_pts2
= found_pts1
= mpg_d
->last_pts
; //the most recently found pts
170 found_pts3
= found_pts2
;
171 found_pts2
= found_pts1
;
172 found_pts1
= mpg_d
->last_pts
;
178 if(found
== 3) pts
= found_pts3
;
180 //clean up from searching of first pts;
181 demux_flush(demuxer
);
186 /// Open an mpg physical stream
187 static demuxer_t
* demux_mpg_open(demuxer_t
* demuxer
) {
188 stream_t
*s
= demuxer
->stream
;
189 mpg_demuxer_t
* mpg_d
;
191 if (!ds_fill_buffer(demuxer
->video
)) return 0;
192 mpg_d
= calloc(1,sizeof(mpg_demuxer_t
));
195 demuxer
->priv
= mpg_d
;
196 mpg_d
->last_pts
= -1.0;
197 mpg_d
->first_pts
= -1.0;
199 //if seeking is allowed set has_valid_timestamps if appropriate
201 && (demuxer
->stream
->type
== STREAMTYPE_FILE
202 || demuxer
->stream
->type
== STREAMTYPE_VCD
)
203 && demuxer
->movi_start
!= demuxer
-> movi_end
206 //We seek to the beginning of the stream, to somewhere in the
207 //middle, and to the end of the stream, while remembering the pts
208 //at each of the three positions. With these pts, we check whether
209 //or not the pts are "linear enough" to justify seeking by the pts
212 //The position where the stream is now
213 off_t pos
= stream_tell(s
);
214 float first_pts
= read_first_mpeg_pts_at_position(demuxer
, demuxer
->movi_start
);
215 if(first_pts
!= -1.0)
217 float middle_pts
= read_first_mpeg_pts_at_position(demuxer
, (demuxer
->movi_end
+ demuxer
->movi_start
)/2);
218 if(middle_pts
!= -1.0)
220 float final_pts
= read_first_mpeg_pts_at_position(demuxer
, demuxer
->movi_end
- TIMESTAMP_PROBE_LEN
);
221 if(final_pts
!= -1.0)
223 // found proper first, middle, and final pts.
224 float proportion
= (middle_pts
-first_pts
==0) ? -1 : (final_pts
-middle_pts
)/(middle_pts
-first_pts
);
225 // if they are linear enough set has_valid_timestamps
226 if((0.5 < proportion
) && (proportion
< 2))
228 mpg_d
->first_pts
= first_pts
;
229 mpg_d
->first_to_final_pts_len
= final_pts
- first_pts
;
230 mpg_d
->has_valid_timestamps
= 1;
236 //Cleaning up from seeking in stream
237 demuxer
->stream
->eof
=0;
238 demuxer
->video
->eof
=0;
239 demuxer
->audio
->eof
=0;
242 ds_fill_buffer(demuxer
->video
);
243 } // if ( demuxer->seekable )
248 static void demux_close_mpg(demuxer_t
* demuxer
) {
249 mpg_demuxer_t
* mpg_d
= demuxer
->priv
;
254 static unsigned long long read_mpeg_timestamp(stream_t
*s
,int c
){
256 unsigned long long pts
;
257 d
=stream_read_word(s
);
258 e
=stream_read_word(s
);
259 if( ((c
&1)!=1) || ((d
&1)!=1) || ((e
&1)!=1) ){
261 return 0; // invalid pts
263 pts
=(((uint64_t)((c
>>1)&7))<<30)|((d
>>1)<<15)|(e
>>1);
264 mp_dbg(MSGT_DEMUX
,MSGL_DBG3
," pts {%llu}",pts
);
268 static void new_audio_stream(demuxer_t
*demux
, int aid
){
269 if(!demux
->a_streams
[aid
]){
270 mpg_demuxer_t
*mpg_d
=(mpg_demuxer_t
*)demux
->priv
;
272 new_sh_audio(demux
,aid
);
273 sh_a
= (sh_audio_t
*)demux
->a_streams
[aid
];
274 sh_a
->needs_parsing
= 1;
275 switch(aid
& 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id)
276 case 0x00: sh_a
->format
=0x50;break; // mpeg
277 case 0xA0: sh_a
->format
=0x10001;break; // dvd pcm
278 case 0x80: if((aid
& 0xF8) == 0x88) sh_a
->format
=0x2001;//dts
279 else sh_a
->format
=0x2000;break; // ac3
282 if((aid
& 0xC0) == 0xC0) sh_a
->format
=0x2000;
283 else if(aid
>= 0x98 && aid
<= 0x9f) sh_a
->format
=0x2001;
284 if (mpg_d
) mpg_d
->a_stream_ids
[mpg_d
->num_a_streams
++] = aid
;
286 if(demux
->audio
->id
==-1) demux
->audio
->id
=aid
;
289 static int demux_mpg_read_packet(demuxer_t
*demux
,int id
){
292 int set_pts
=0; // !=0 iff pts has been set to a proper value
294 unsigned long long pts
=0;
295 unsigned long long dts av_unused
= 0;
297 int pes_ext2_subid
=-1;
298 double stream_pts
= MP_NOPTS_VALUE
;
299 demux_stream_t
*ds
=NULL
;
301 mpg_demuxer_t
*priv
= (mpg_demuxer_t
*) demux
->priv
;
303 mp_dbg(MSGT_DEMUX
,MSGL_DBG3
,"demux_read_packet: %X\n",id
);
306 // demux->synced=0; // force resync after 0x1F0
310 // if(id==0x1BA) packet_start_pos=stream_tell(demux->stream);
311 if((id
<0x1BC || id
>=0x1F0) && id
!= 0x1FD) return -1;
312 if(id
==0x1BE) return -1; // padding stream
313 if(id
==0x1BF) return -1; // private2
315 len
=stream_read_word(demux
->stream
);
316 mp_dbg(MSGT_DEMUX
,MSGL_DBG3
,"PACKET len=%d",len
);
317 // if(len==62480){ demux->synced=0;return -1;} /* :) */
318 if(len
==0 || len
>MAX_PS_PACKETSIZE
){
319 mp_dbg(MSGT_DEMUX
,MSGL_DBG2
,"Invalid PS packet len: %d\n",len
);
320 return -2; // invalid packet !!!!!!
326 parse_psm(demux
, len
);
330 while(len
>0){ // Skip stuFFing bytes
331 c
=stream_read_char(demux
->stream
);
335 if((c
>>6)==1){ // Read (skip) STD scale & size value
336 // printf(" STD_scale=%d",(c>>5)&1);
337 d
=((c
&0x1F)<<8)|stream_read_char(demux
->stream
);
339 // printf(" STD_size=%d",d);
340 c
=stream_read_char(demux
->stream
);
342 // Read System-1 stream timestamps:
344 pts
=read_mpeg_timestamp(demux
->stream
,c
);
349 pts
=read_mpeg_timestamp(demux
->stream
,c
);
350 c
=stream_read_char(demux
->stream
);
351 if((c
>>4)!=1) pts
=0; //printf("{ERROR4}");
353 dts
=read_mpeg_timestamp(demux
->stream
,c
);
360 // System-2 (.VOB) stream:
361 c
=stream_read_char(demux
->stream
);
363 parse_ext2
= (id
== 0x1FD) && ((c
& 0x3F) == 1);
364 c
=stream_read_char(demux
->stream
);
367 mp_dbg(MSGT_DEMUX
,MSGL_DBG3
," hdrlen=%d (len=%d)",hdrlen
,len
);
368 if(hdrlen
>len
){ mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_mpg: invalid header length \n"); return -1;}
369 if(pts_flags
==2 && hdrlen
>=5){
370 c
=stream_read_char(demux
->stream
);
371 pts
=read_mpeg_timestamp(demux
->stream
,c
);
375 if(pts_flags
==3 && hdrlen
>=10){
376 c
=stream_read_char(demux
->stream
);
377 pts
=read_mpeg_timestamp(demux
->stream
,c
);
379 c
=stream_read_char(demux
->stream
);
380 dts
=read_mpeg_timestamp(demux
->stream
,c
);
384 if(parse_ext2
&& hdrlen
>=3) {
385 c
=stream_read_char(demux
->stream
);
388 if((c
& 0x0F) != 0x0F) {
389 mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_mpg: pes_extension_flag2 not set, discarding pes packet\n");
392 if(c
& 0x80) { //pes_private_data_flag
394 mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_mpg: not enough pes_private_data bytes: %d < 16, discarding pes packet\n", hdrlen
);
397 stream_skip(demux
->stream
, 16);
400 if(c
& 0x40) { //pack_header_field_flag
401 int l
= stream_read_char(demux
->stream
);
402 if(l
< 0) //couldn't read from the stream?
405 if(l
< 0 || hdrlen
< l
) {
406 mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_mpg: not enough pack_header bytes: hdrlen: %d < skip: %d, discarding pes packet\n",
410 stream_skip(demux
->stream
, l
);
413 if(c
& 0x20) { //program_packet_sequence_counter_flag
415 mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_mpg: not enough program_packet bytes: hdrlen: %d, discarding pes packet\n", hdrlen
);
418 stream_skip(demux
->stream
, 2);
423 stream_skip(demux
->stream
, 2);
426 c
=stream_read_char(demux
->stream
); //pes_extension2 flag
428 if(c
!=0x81) { mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_mpg: unknown pes_extension2 format, len is > 1 \n"); return -1;}
429 c
=stream_read_char(demux
->stream
); //pes_extension2 payload === substream id
431 if(c
<0x55 || c
>0x5F) { mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_mpg: unknown vc1 substream_id: 0x%x \n", c
); return -1;}
435 stream_skip(demux
->stream
,hdrlen
); // skip header and stuffing bytes
437 if(id
==0x1FD && pes_ext2_subid
!=-1) {
438 //==== EVO VC1 STREAMS ===//
439 if(!demux
->v_streams
[pes_ext2_subid
]) new_sh_video(demux
,pes_ext2_subid
);
440 if(demux
->video
->id
==-1) demux
->video
->id
=pes_ext2_subid
;
441 if(demux
->video
->id
==pes_ext2_subid
){
443 if(!ds
->sh
) ds
->sh
=demux
->v_streams
[pes_ext2_subid
];
445 sh_video_t
*sh
= (sh_video_t
*)ds
->sh
;
446 sh
->format
= mmioFOURCC('W', 'V', 'C', '1');
450 //============== DVD Audio sub-stream ======================
456 tmppos
= stream_tell(demux
->stream
);
457 tmp
= stream_read_word(demux
->stream
);
458 stream_seek(demux
->stream
, tmppos
);
459 /// vdr stores A52 without the 4 header bytes, so we have to check this condition first
465 aid
=stream_read_char(demux
->stream
);--len
;
466 if(len
<3) return -1; // invalid audio packet
470 // 0x20..0x3F subtitle
471 // 0x80..0x87 and 0xC0..0xCF AC3 audio
472 // 0x88..0x8F and 0x98..0x9F DTS audio
473 // 0xA0..0xBF PCM audio
475 if((aid
& 0xE0) == 0x20){
479 if(!demux
->s_streams
[aid
]){
480 sh_sub_t
*sh
= new_sh_sub(demux
, aid
);
481 if (sh
) sh
->type
= 'v';
482 mp_msg(MSGT_DEMUX
,MSGL_V
,"==> Found subtitle: %d\n",aid
);
485 if(demux
->sub
->id
> -1)
486 demux
->sub
->id
&= 0x1F;
487 if(!demux
->opts
->sub_lang
&& demux
->sub
->id
== -1)
488 demux
->sub
->id
= aid
;
489 if(demux
->sub
->id
==aid
){
492 } else if((aid
>= 0x80 && aid
<= 0x8F) || (aid
>= 0x98 && aid
<= 0xAF) || (aid
>= 0xC0 && aid
<= 0xCF)) {
494 // aid=128+(aid&0x7F);
496 new_audio_stream(demux
, aid
);
497 if(demux
->audio
->id
==aid
){
500 if(!ds
->sh
) ds
->sh
=demux
->a_streams
[aid
];
501 // READ Packet: Skip additional audio header data:
503 c
=stream_read_char(demux
->stream
);//num of frames
504 type
=stream_read_char(demux
->stream
);//startpos hi
505 type
=(type
<<8)|stream_read_char(demux
->stream
);//startpos lo
506 // printf("\r[%02X][%04X]",c,type);
509 if((aid
&0xE0)==0xA0 && len
>=3){
511 // save audio header as codecdata!
512 if(!((sh_audio_t
*)(ds
->sh
))->codecdata_len
){
513 ((sh_audio_t
*)(ds
->sh
))->codecdata
=malloc(3);
514 ((sh_audio_t
*)(ds
->sh
))->codecdata_len
=3;
516 hdr
=((sh_audio_t
*)(ds
->sh
))->codecdata
;
518 // emphasis[1], mute[1], rvd[1], frame number[5]:
519 hdr
[0]=stream_read_char(demux
->stream
);
520 // printf(" [%01X:%02d]",c>>5,c&31);
521 // quantization[2],freq[2],rvd[1],channels[3]
522 hdr
[1]=stream_read_char(demux
->stream
);
523 // printf("[%01X:%01X] ",c>>4,c&15);
524 // dynamic range control (0x80=off):
525 hdr
[2]=stream_read_char(demux
->stream
);
526 // printf("[%02X] ",c);
528 if(len
<=0) mp_msg(MSGT_DEMUX
,MSGL_V
,"End of packet while searching for PCM header\n");
531 } // if(demux->audio->id==aid)
533 } else mp_msg(MSGT_DEMUX
,MSGL_V
,"Unknown 0x1BD substream: 0x%02X \n",aid
);
537 mp_msg(MSGT_DEMUX
,MSGL_V
," {ERROR5,c=%d} \n",c
);
538 return -1; // invalid packet !!!!!!
541 if(mpeg_pts_error
) mp_msg(MSGT_DEMUX
,MSGL_V
," {PTS_err:%d} \n",mpeg_pts_error
);
542 mp_dbg(MSGT_DEMUX
,MSGL_DBG3
," => len=%d\n",len
);
544 // if(len<=0 || len>MAX_PS_PACKETSIZE) return -1; // Invalid packet size
545 if(len
<=0 || len
>MAX_PS_PACKETSIZE
){
546 mp_dbg(MSGT_DEMUX
,MSGL_DBG2
,"Invalid PS data len: %d\n",len
);
547 return -1; // invalid packet !!!!!!
550 if(id
>=0x1C0 && id
<=0x1DF){
553 new_audio_stream(demux
, aid
);
554 if(demux
->audio
->id
==aid
){
556 if(!ds
->sh
) ds
->sh
=demux
->a_streams
[aid
];
558 sh_audio_t
*sh
= (sh_audio_t
*)ds
->sh
;
559 if(priv
->es_map
[id
- 0x1B0])
560 sh
->format
= priv
->es_map
[id
- 0x1B0];
561 mp_dbg(MSGT_DEMUX
,MSGL_DBG2
,"ASSIGNED TO STREAM %d CODEC %x\n", id
, priv
->es_map
[id
- 0x1B0]);
565 if(id
>=0x1E0 && id
<=0x1EF){
568 if(!demux
->v_streams
[aid
]) new_sh_video(demux
,aid
);
569 if(demux
->video
->id
==-1) demux
->video
->id
=aid
;
570 if(demux
->video
->id
==aid
){
572 if(!ds
->sh
) ds
->sh
=demux
->v_streams
[aid
];
574 sh_video_t
*sh
= (sh_video_t
*)ds
->sh
;
575 if(priv
->es_map
[id
- 0x1B0]) {
576 sh
->format
= priv
->es_map
[id
- 0x1B0];
577 mp_dbg(MSGT_DEMUX
,MSGL_DBG2
,"ASSIGNED TO STREAM %d CODEC %x\n", id
, priv
->es_map
[id
- 0x1B0]);
584 mp_dbg(MSGT_DEMUX
,MSGL_DBG2
,"DEMUX_MPG: Read %d data bytes from packet %04X\n",len
,id
);
585 // printf("packet start = 0x%X \n",stream_tell(demux->stream)-packet_start_pos);
587 dp
=new_demux_packet(len
);
589 mp_dbg(MSGT_DEMUX
,MSGL_ERR
,"DEMUX_MPG ERROR: couldn't create demux_packet(%d bytes)\n",len
);
590 stream_skip(demux
->stream
,len
);
593 l
= stream_read(demux
->stream
,dp
->buffer
,len
);
595 resize_demux_packet(dp
, l
);
598 dp
->pts
=pts
/90000.0f
;
599 dp
->pos
=demux
->filepos
;
602 set dp->stream_pts only when feeding the video stream, or strangely interleaved files
603 (such as SWIII) will show strange alternations in the stream time, wildly going
606 if(ds
== demux
->video
&& stream_control(demux
->stream
, STREAM_CTRL_GET_CURRENT_TIME
,(void *)&stream_pts
)!=STREAM_UNSUPPORTED
)
607 dp
->stream_pts
= stream_pts
;
608 ds_add_packet(ds
,dp
);
609 if (demux
->priv
&& set_pts
) ((mpg_demuxer_t
*)demux
->priv
)->last_pts
= pts
/90000.0f
;
610 // if(ds==demux->sub) parse_dvdsub(ds->last->buffer,ds->last->len);
613 mp_dbg(MSGT_DEMUX
,MSGL_DBG2
,"DEMUX_MPG: Skipping %d data bytes from packet %04X\n",len
,id
);
614 if(len
<=2356) stream_skip(demux
->stream
,len
);
618 static int num_elementary_packets100
=0;
619 static int num_elementary_packets101
=0;
620 static int num_elementary_packets12x
=0;
621 static int num_elementary_packets1B6
=0;
622 static int num_elementary_packetsPES
=0;
623 static int num_mpeg12_startcode
=0;
624 static int num_h264_slice
=0; //combined slice
625 static int num_h264_dpa
=0; //DPA Slice
626 static int num_h264_dpb
=0; //DPB Slice
627 static int num_h264_dpc
=0; //DPC Slice
628 static int num_h264_idr
=0; //IDR Slice
629 static int num_h264_sps
=0;
630 static int num_h264_pps
=0;
632 static int num_mp3audio_packets
=0;
634 static void clear_stats(void)
636 num_elementary_packets100
=0;
637 num_elementary_packets101
=0;
638 num_elementary_packets1B6
=0;
639 num_elementary_packets12x
=0;
640 num_elementary_packetsPES
=0;
641 num_mpeg12_startcode
=0;
642 num_h264_slice
=0; //combined slice
643 num_h264_dpa
=0; //DPA Slice
644 num_h264_dpb
=0; //DPB Slice
645 num_h264_dpc
=0; //DPC Slice
646 num_h264_idr
=0; //IDR Slice
649 num_mp3audio_packets
=0;
652 //assumes demuxer->synced < 2
653 static inline void update_stats(int head
)
655 if(head
==0x1B6) ++num_elementary_packets1B6
;
656 else if(head
==0x1B3 || head
==0x1B8) ++num_mpeg12_startcode
;
657 else if(head
==0x100) ++num_elementary_packets100
;
658 else if(head
==0x101) ++num_elementary_packets101
;
659 else if(head
==0x1BD || (0x1C0<=head
&& head
<=0x1EF))
660 num_elementary_packetsPES
++;
661 else if(head
>=0x120 && head
<=0x12F) ++num_elementary_packets12x
;
662 if(head
>=0x100 && head
<0x1B0)
664 if((head
&~0x60) == 0x101) ++num_h264_slice
;
665 else if((head
&~0x60) == 0x102) ++num_h264_dpa
;
666 else if((head
&~0x60) == 0x103) ++num_h264_dpb
;
667 else if((head
&~0x60) == 0x104) ++num_h264_dpc
;
668 else if((head
&~0x60) == 0x105 && head
!= 0x105) ++num_h264_idr
;
669 else if((head
&~0x60) == 0x107 && head
!= 0x107) ++num_h264_sps
;
670 else if((head
&~0x60) == 0x108 && head
!= 0x108) ++num_h264_pps
;
674 static int demux_mpg_probe(demuxer_t
*demuxer
) {
675 int pes av_unused
= 1;
678 int file_format
= DEMUXER_TYPE_UNKNOWN
;
680 tmppos
=stream_tell(demuxer
->stream
);
681 tmp
=stream_read_dword(demuxer
->stream
);
682 if(tmp
==0x1E0 || tmp
==0x1C0) {
683 tmp
=stream_read_word(demuxer
->stream
);
684 if(tmp
>1 && tmp
<=2048) pes
=0; // demuxer->synced=3; // PES...
686 stream_seek(demuxer
->stream
,tmppos
);
690 if(demux_mpg_open(demuxer
))
691 file_format
=DEMUXER_TYPE_MPEG_PS
;
693 mp_msg(MSGT_DEMUX
,MSGL_V
,"MPEG packet stats: p100: %d p101: %d p1B6: %d p12x: %d sli: %d a: %d b: %d c: %d idr: %d sps: %d pps: %d PES: %d MP3: %d, synced: %d\n",
694 num_elementary_packets100
,num_elementary_packets101
,
695 num_elementary_packets1B6
,num_elementary_packets12x
,
696 num_h264_slice
, num_h264_dpa
,
697 num_h264_dpb
, num_h264_dpc
=0,
698 num_h264_idr
, num_h264_sps
=0,
700 num_elementary_packetsPES
,num_mp3audio_packets
, demuxer
->synced
);
702 //MPEG packet stats: p100: 458 p101: 458 PES: 0 MP3: 1103 (.m2v)
703 if(num_mp3audio_packets
>50 && num_mp3audio_packets
>2*num_elementary_packets100
704 && abs(num_elementary_packets100
-num_elementary_packets101
)>2)
707 // some hack to get meaningfull error messages to our unhappy users:
708 if(num_mpeg12_startcode
>=2 && num_elementary_packets100
>=2 && num_elementary_packets101
>=2 &&
709 abs(num_elementary_packets101
+8-num_elementary_packets100
)<16) {
710 if(num_elementary_packetsPES
>=4 && num_elementary_packetsPES
>=num_elementary_packets100
-4) {
713 file_format
=DEMUXER_TYPE_MPEG_ES
; // <-- hack is here :)
715 // fuzzy mpeg4-es detection. do NOT enable without heavy testing of mpeg formats detection!
716 if(num_elementary_packets1B6
>3 && num_elementary_packets12x
>=1 &&
717 num_elementary_packetsPES
==0 && num_elementary_packets100
<=num_elementary_packets12x
&&
719 file_format
=DEMUXER_TYPE_MPEG4_ES
;
721 // fuzzy h264-es detection. do NOT enable without heavy testing of mpeg formats detection!
722 if((num_h264_slice
>3 || (num_h264_dpa
>3 && num_h264_dpb
>3 && num_h264_dpc
>3)) &&
723 /* FIXME num_h264_sps>=1 && */ num_h264_pps
>=1 && num_h264_idr
>=1 &&
724 num_elementary_packets1B6
==0 && num_elementary_packetsPES
==0 &&
726 file_format
=DEMUXER_TYPE_H264_ES
;
729 if(demuxer
->synced
==2)
730 mp_msg(MSGT_DEMUXER
, MSGL_ERR
, "MPEG: %s",
731 mp_gtext("Missing video stream!? Contact the author, it may be a bug :(\n"));
733 mp_tmsg(MSGT_DEMUXER
,MSGL_V
,"Not MPEG System Stream format... (maybe Transport Stream?)\n");
736 //FIXME this shouldn't be necessary
737 stream_seek(demuxer
->stream
,tmppos
);
741 static int demux_mpg_es_fill_buffer(demuxer_t
*demux
, demux_stream_t
*ds
){
742 // Elementary video stream
743 if(demux
->stream
->eof
) return 0;
744 demux
->filepos
=stream_tell(demux
->stream
);
745 ds_read_packet(demux
->video
,demux
->stream
,STREAM_BUFFER_SIZE
,0,demux
->filepos
,0);
750 * \brief discard until 0x100 header and return a filled buffer
751 * \param b buffer-end pointer
752 * \param pos current pos in stream, negative since b points to end of buffer
753 * \param s stream to read from
754 * \return new position, differs from original pos when eof hit and thus
755 * b was modified to point to the new end of buffer
757 static int find_end(unsigned char **b
, int pos
, stream_t
*s
) {
758 register int state
= 0xffffffff;
759 unsigned char *buf
= *b
;
762 // search already read part
763 while (state
!= 0x100 && pos
) {
764 state
= state
<< 8 | buf
[pos
++];
766 // continue search in stream
767 while (state
!= 0x100) {
768 register int c
= stream_read_char(s
);
770 state
= state
<< 8 | c
;
772 // modify previous header (from 0x1bc or 0x1bf to 0x100)
774 // copy remaining buffer part to current pos
775 memmove(&buf
[start
], &buf
[pos
], -pos
);
776 unused
= start
+ -pos
; // -unused bytes in buffer
777 read
= stream_read(s
, &buf
[unused
], -unused
);
779 // fix buffer so it ends at pos == 0 (eof case)
786 * This format usually uses an insane bitrate, which makes this function
787 * performance-critical!
788 * Be sure to benchmark any changes with different compiler versions.
790 static int demux_mpg_gxf_fill_buffer(demuxer_t
*demux
, demux_stream_t
*ds
) {
791 demux_packet_t
*pack
;
793 demux
->filepos
= stream_tell(demux
->stream
);
794 pack
= new_demux_packet(STREAM_BUFFER_SIZE
);
795 len
= stream_read(demux
->stream
, pack
->buffer
, STREAM_BUFFER_SIZE
);
798 free_demux_packet(pack
);
802 register uint32_t state
= (uint32_t)demux
->priv
;
803 register int pos
= -len
;
804 unsigned char *buf
= &pack
->buffer
[len
];
806 state
= state
<< 8 | buf
[pos
];
807 if (unlikely((state
| 3) == 0x1bf))
808 pos
= find_end(&buf
, pos
, demux
->stream
);
810 demux
->priv
= (void *)state
;
811 len
= buf
- pack
->buffer
;
813 if (len
< STREAM_BUFFER_SIZE
)
814 resize_demux_packet(pack
, len
);
815 ds_add_packet(ds
, pack
);
819 static int demux_mpg_fill_buffer(demuxer_t
*demux
, demux_stream_t
*ds
)
823 int max_packs
=256; // 512kbyte
828 demux
->filepos
=stream_tell(demux
->stream
);
829 //lame workaround: this is needed to show the progress bar when playing dvdnav://
830 //(ths poor guy doesn't know teh length of the stream at startup)
831 demux
->movi_end
= demux
->stream
->end_pos
;
832 head
=stream_read_dword(demux
->stream
);
833 if((head
&0xFFFFFF00)!=0x100){
835 demux
->filepos
-=skipped
;
837 int c
=stream_read_char(demux
->stream
);
842 if(mp_check_mp3_header(head
)) ++num_mp3audio_packets
;
843 ++skipped
; //++demux->filepos;
849 demux
->filepos
+=skipped
;
851 if(stream_eof(demux
->stream
)) break;
852 // sure: head=0x000001XX
853 mp_dbg(MSGT_DEMUX
,MSGL_DBG4
,"*** head=0x%X\n",head
);
854 if(demux
->synced
==0){
855 if(head
==0x1BA) demux
->synced
=1; //else
856 // if(head==0x1BD || (head>=0x1C0 && head<=0x1EF)) demux->synced=3; // PES?
858 if(demux
->synced
==1){
859 if(head
==0x1BB || head
==0x1BD || (head
>=0x1C0 && head
<=0x1EF)){
861 mp_msg(MSGT_DEMUX
,MSGL_V
,"system stream synced at 0x%"PRIX64
" (%"PRId64
")!\n",(int64_t)demux
->filepos
,(int64_t)demux
->filepos
);
862 num_elementary_packets100
=0; // requires for re-sync!
863 num_elementary_packets101
=0; // requires for re-sync!
864 } else demux
->synced
=0;
866 if(demux
->synced
>=2){
867 ret
=demux_mpg_read_packet(demux
,head
);
870 demux
->stream
->eof
=1;
871 mp_tmsg(MSGT_DEMUX
,MSGL_ERR
,"demux: File doesn't contain the selected audio or video stream.\n");
874 if(demux
->synced
==3) demux
->synced
=(ret
==1)?2:0; // PES detect
877 if(head
>=0x100 && head
<0x1B0)
878 mp_msg(MSGT_DEMUX
,MSGL_DBG3
,"Opps... elementary video packet found: %03X\n",head
);
879 else if((head
>=0x1C0 && head
<0x1F0) || head
==0x1BD)
880 mp_msg(MSGT_DEMUX
,MSGL_DBG3
,"Opps... PES packet found: %03X\n",head
);
882 if(((num_elementary_packets100
>50 && num_elementary_packets101
>50) ||
883 (num_elementary_packetsPES
>50)) && skipped
>4000000){
884 mp_msg(MSGT_DEMUX
,MSGL_V
,"sync_mpeg_ps: seems to be ES/PES stream...\n");
885 demux
->stream
->eof
=1;
888 if(num_mp3audio_packets
>100 && num_elementary_packets100
<10){
889 mp_msg(MSGT_DEMUX
,MSGL_V
,"sync_mpeg_ps: seems to be MP3 stream...\n");
890 demux
->stream
->eof
=1;
895 mp_dbg(MSGT_DEMUX
,MSGL_DBG2
,"demux: %d bad bytes skipped\n",skipped
);
896 if(demux
->stream
->eof
){
897 mp_msg(MSGT_DEMUX
,MSGL_V
,"MPEG Stream reached EOF\n");
903 static void demux_seek_mpg(demuxer_t
*demuxer
, float rel_seek_secs
,
904 float audio_delay
, int flags
)
906 demux_stream_t
*d_audio
=demuxer
->audio
;
907 demux_stream_t
*d_video
=demuxer
->video
;
908 sh_audio_t
*sh_audio
=d_audio
->sh
;
909 sh_video_t
*sh_video
=d_video
->sh
;
910 mpg_demuxer_t
*mpg_d
=(mpg_demuxer_t
*)demuxer
->priv
;
913 off_t oldpos
= demuxer
->filepos
;
915 off_t newpos
= (flags
& SEEK_ABSOLUTE
) ? demuxer
->movi_start
: oldpos
;
918 oldpts
= mpg_d
->last_pts
;
919 newpts
= (flags
& SEEK_ABSOLUTE
) ? 0.0 : oldpts
;
920 //================= seek in MPEG ==========================
921 //calculate the pts to seek to
922 if(flags
& SEEK_FACTOR
) {
923 if (mpg_d
&& mpg_d
->first_to_final_pts_len
> 0.0)
924 newpts
+= mpg_d
->first_to_final_pts_len
* rel_seek_secs
;
926 newpts
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) * oldpts
/ oldpos
;
928 newpts
+= rel_seek_secs
;
929 if (newpts
< 0) newpts
= 0;
931 if(flags
&SEEK_FACTOR
){
933 newpos
+=(demuxer
->movi_end
-demuxer
->movi_start
)*rel_seek_secs
;
936 if (mpg_d
&& mpg_d
->has_valid_timestamps
) {
937 if (mpg_d
->first_to_final_pts_len
> 0.0)
938 newpos
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) / mpg_d
->first_to_final_pts_len
;
939 else if (oldpts
> 0.0)
940 newpos
+= rel_seek_secs
* (oldpos
- demuxer
->movi_start
) / oldpts
;
941 } else if(!sh_video
|| !sh_video
->i_bps
) // unspecified or VBR
942 newpos
+=2324*75*rel_seek_secs
; // 174.3 kbyte/sec
944 newpos
+=sh_video
->i_bps
*rel_seek_secs
;
948 if(newpos
<demuxer
->movi_start
){
949 if(demuxer
->stream
->type
!=STREAMTYPE_VCD
) demuxer
->movi_start
=0; // for VCD
950 if(newpos
<demuxer
->movi_start
) newpos
=demuxer
->movi_start
;
953 stream_seek(demuxer
->stream
,newpos
);
956 videobuf_code_len
=0; // reset ES stream buffer
958 ds_fill_buffer(d_video
);
960 ds_fill_buffer(d_audio
);
965 if(sh_audio
&& !d_audio
->eof
&& d_video
->pts
&& d_audio
->pts
){
966 float a_pts
=d_audio
->pts
;
967 a_pts
+=(ds_tell_pts(d_audio
)-sh_audio
->a_in_buffer_len
)/(float)sh_audio
->i_bps
;
968 if(d_video
->pts
>a_pts
){
969 skip_audio_frame(sh_audio
); // sync audio
974 i
=sync_video_packet(d_video
);
975 if(sh_video
->format
== mmioFOURCC('W', 'V', 'C', '1')) {
976 if(i
==0x10E || i
==0x10F) //entry point or sequence header
979 if(sh_video
->format
== 0x10000004) { //mpeg4
980 if(i
==0x1B6) { //vop (frame) startcode
981 int pos
= videobuf_len
;
982 if(!read_video_packet(d_video
)) break; // EOF
983 if((videobuffer
[pos
+4] & 0x3F) == 0) break; //I-frame
985 } else if(sh_video
->format
== 0x10000005){ //h264
986 if((i
& ~0x60) == 0x105) break;
987 } else { //default mpeg1/2
988 if(i
==0x1B3 || i
==0x1B8) break; // found it!
990 if(!i
|| !skip_video_packet(d_video
)) break; // EOF?
994 if (!precision
|| abs(newpts
- mpg_d
->last_pts
) < 0.5 || (mpg_d
->last_pts
== oldpts
)) break;
995 if ((newpos
- oldpos
) * (mpg_d
->last_pts
- oldpts
) < 0) { // invalid timestamps
996 mpg_d
->has_valid_timestamps
= 0;
1000 //prepare another seek because we are off by more than 0.5s
1002 newpos
+= (newpts
- mpg_d
->last_pts
) * (newpos
- oldpos
) / (mpg_d
->last_pts
- oldpts
);
1003 demux_flush(demuxer
);
1004 demuxer
->stream
->eof
=0; // clear eof flag
1011 static int demux_mpg_control(demuxer_t
*demuxer
, int cmd
, void *arg
)
1013 mpg_demuxer_t
*mpg_d
=(mpg_demuxer_t
*)demuxer
->priv
;
1016 case DEMUXER_CTRL_GET_TIME_LENGTH
:
1017 if(stream_control(demuxer
->stream
, STREAM_CTRL_GET_TIME_LENGTH
, arg
) != STREAM_UNSUPPORTED
) {
1018 mp_msg(MSGT_DEMUXER
,MSGL_DBG2
,"\r\nDEMUX_MPG_CTRL, (%.3f)\r\n", *((double*)arg
));
1019 return DEMUXER_CTRL_GUESS
;
1021 if (mpg_d
&& mpg_d
->has_valid_timestamps
) {
1022 *((double *)arg
)=(double)mpg_d
->first_to_final_pts_len
;
1023 return DEMUXER_CTRL_OK
;
1025 return DEMUXER_CTRL_DONTKNOW
;
1027 case DEMUXER_CTRL_GET_PERCENT_POS
:
1028 if (mpg_d
&& mpg_d
->has_valid_timestamps
&& mpg_d
->first_to_final_pts_len
> 0.0) {
1029 *((int *)arg
)=(int)(100 * (mpg_d
->last_pts
-mpg_d
->first_pts
) / mpg_d
->first_to_final_pts_len
);
1030 return DEMUXER_CTRL_OK
;
1032 return DEMUXER_CTRL_DONTKNOW
;
1034 case DEMUXER_CTRL_SWITCH_AUDIO
:
1035 if(! (mpg_d
&& mpg_d
->num_a_streams
> 1 && demuxer
->audio
&& demuxer
->audio
->sh
))
1036 return DEMUXER_CTRL_NOTIMPL
;
1038 demux_stream_t
*d_audio
= demuxer
->audio
;
1039 sh_audio_t
*sh_audio
= d_audio
->sh
;
1040 sh_audio_t
*sh_a
= sh_audio
;
1043 return DEMUXER_CTRL_NOTIMPL
;
1044 if (*((int*)arg
) < 0)
1046 for (i
= 0; i
< mpg_d
->num_a_streams
; i
++) {
1047 if (d_audio
->id
== mpg_d
->a_stream_ids
[i
]) break;
1049 i
= (i
+1) % mpg_d
->num_a_streams
;
1050 sh_a
= (sh_audio_t
*)demuxer
->a_streams
[mpg_d
->a_stream_ids
[i
]];
1053 for (i
= 0; i
< mpg_d
->num_a_streams
; i
++)
1054 if (*((int*)arg
) == mpg_d
->a_stream_ids
[i
]) break;
1055 if (i
< mpg_d
->num_a_streams
)
1056 sh_a
= (sh_audio_t
*)demuxer
->a_streams
[*((int*)arg
)];
1058 if (i
< mpg_d
->num_a_streams
&& d_audio
->id
!= mpg_d
->a_stream_ids
[i
]) {
1059 d_audio
->id
= mpg_d
->a_stream_ids
[i
];
1061 ds_free_packs(d_audio
);
1064 *((int*)arg
) = demuxer
->audio
->id
;
1065 return DEMUXER_CTRL_OK
;
1068 return DEMUXER_CTRL_NOTIMPL
;
1073 static int demux_mpg_pes_probe(demuxer_t
*demuxer
) {
1074 demuxer
->synced
= 3;
1075 return (demux_mpg_probe(demuxer
) == DEMUXER_TYPE_MPEG_PS
) ? DEMUXER_TYPE_MPEG_PES
: 0;
1079 static demuxer_t
* demux_mpg_es_open(demuxer_t
* demuxer
)
1081 sh_video_t
*sh_video
=NULL
;
1083 demuxer
->audio
->sh
= NULL
; // ES streams has no audio channel
1084 demuxer
->video
->sh
= new_sh_video(demuxer
,0); // create dummy video stream header, id=0
1085 sh_video
=demuxer
->video
->sh
;sh_video
->ds
=demuxer
->video
;
1090 static demuxer_t
*demux_mpg_gxf_open(demuxer_t
*demuxer
) {
1091 demuxer
->audio
->sh
= NULL
;
1092 demuxer
->video
->sh
= new_sh_video(demuxer
,0);
1093 ((sh_video_t
*)demuxer
->video
->sh
)->ds
= demuxer
->video
;
1094 demuxer
->priv
= (void *) 0xffffffff;
1098 static demuxer_t
* demux_mpg_ps_open(demuxer_t
* demuxer
)
1100 sh_audio_t
*sh_audio
=NULL
;
1101 sh_video_t
*sh_video
=NULL
;
1103 sh_video
=demuxer
->video
->sh
;sh_video
->ds
=demuxer
->video
;
1105 if(demuxer
->audio
->id
!=-2) {
1106 if(!ds_fill_buffer(demuxer
->audio
)){
1107 mp_msg(MSGT_DEMUXER
, MSGL_INFO
, "MPEG: %s",
1108 mp_gtext("No audio stream found -> no sound.\n"));
1109 demuxer
->audio
->sh
=NULL
;
1111 sh_audio
=demuxer
->audio
->sh
;sh_audio
->ds
=demuxer
->audio
;
1115 if(!sh_video
->format
&& ps_probe
> 0) {
1117 off_t pos
= stream_tell(demuxer
->stream
);
1121 head
=sync_video_packet(demuxer
->video
);
1124 skip_video_packet(demuxer
->video
);
1125 } while(stream_tell(demuxer
->stream
) < pos
+ ps_probe
&& !demuxer
->stream
->eof
);
1127 ds_free_packs(demuxer
->video
);
1128 demuxer
->stream
->eof
=0;
1129 stream_seek(demuxer
->stream
, pos
);
1130 mp_msg(MSGT_DEMUX
,MSGL_INFO
,"MPEG packet stats: p100: %d p101: %d p1B6: %d p12x: %d sli: %d a: %d b: %d c: %d idr: %d sps: %d pps: %d\n",
1131 num_elementary_packets100
, num_elementary_packets101
,
1132 num_elementary_packets1B6
, num_elementary_packets12x
,
1133 num_h264_slice
, num_h264_dpa
, num_h264_dpb
, num_h264_dpc
,
1134 num_h264_idr
, num_h264_sps
, num_h264_pps
);
1136 if(num_elementary_packets1B6
>3 && num_elementary_packets12x
>=1 &&
1137 num_elementary_packets100
<=num_elementary_packets12x
)
1138 sh_video
->format
= 0x10000004;
1139 else if((num_h264_slice
>3 || (num_h264_dpa
>3 && num_h264_dpb
>3 && num_h264_dpc
>3)) &&
1140 num_h264_sps
>=1 && num_h264_pps
>=1 && num_h264_idr
>=1 &&
1141 num_elementary_packets1B6
==0)
1142 sh_video
->format
= 0x10000005;
1143 else sh_video
->format
= 0x10000002;
1150 const demuxer_desc_t demuxer_desc_mpeg_ps
= {
1156 DEMUXER_TYPE_MPEG_PS
,
1157 0, // unsafe autodetect
1159 demux_mpg_fill_buffer
,
1167 const demuxer_desc_t demuxer_desc_mpeg_pes
= {
1173 DEMUXER_TYPE_MPEG_PES
,
1174 0, // unsafe autodetect
1175 demux_mpg_pes_probe
,
1176 demux_mpg_fill_buffer
,
1184 const demuxer_desc_t demuxer_desc_mpeg_gxf
= {
1185 "MPEG ES in GXF demuxer",
1188 "Reimar Doeffinger",
1190 DEMUXER_TYPE_MPEG_GXF
,
1191 0, // hack autodetection
1193 demux_mpg_gxf_fill_buffer
,
1200 const demuxer_desc_t demuxer_desc_mpeg_es
= {
1206 DEMUXER_TYPE_MPEG_ES
,
1207 0, // hack autodetection
1209 demux_mpg_es_fill_buffer
,
1217 const demuxer_desc_t demuxer_desc_mpeg4_es
= {
1223 DEMUXER_TYPE_MPEG4_ES
,
1224 0, // hack autodetection
1226 demux_mpg_es_fill_buffer
,
1234 const demuxer_desc_t demuxer_desc_h264_es
= {
1240 DEMUXER_TYPE_H264_ES
,
1241 0, // hack autodetection
1243 demux_mpg_es_fill_buffer
,