Add missing #include, fixes the warning:
[mplayer/greg.git] / libmpdemux / demux_mpg.c
blob45dfec1af4161bd85dc6132a9f74a54abab41377
1 // MPG/VOB file parser for DEMUXER v2.5 by A'rpi/ESP-team
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <math.h>
8 #include "config.h"
9 #include "mp_msg.h"
10 #include "help_mp.h"
12 #include "stream/stream.h"
13 #include "demuxer.h"
14 #include "parse_es.h"
15 #include "stheader.h"
16 #include "mp3_hdr.h"
18 //#define MAX_PS_PACKETSIZE 2048
19 #define MAX_PS_PACKETSIZE (224*1024)
21 #define UNKNOWN 0
22 #define VIDEO_MPEG1 0x10000001
23 #define VIDEO_MPEG2 0x10000002
24 #define VIDEO_MPEG4 0x10000004
25 #define VIDEO_H264 0x10000005
26 #define AUDIO_MP2 0x50
27 #define AUDIO_A52 0x2000
28 #define AUDIO_LPCM_BE 0x10001
29 #define AUDIO_AAC mmioFOURCC('M', 'P', '4', 'A')
31 typedef struct mpg_demuxer {
32 float last_pts;
33 float first_pts; // first pts found in stream
34 float first_to_final_pts_len; // difference between final pts and first pts
35 int has_valid_timestamps; // !=0 iff time stamps look linear
36 // (not necessarily starting with 0)
37 unsigned int es_map[0x40]; //es map of stream types (associated to the pes id) from 0xb0 to 0xef
38 int num_a_streams;
39 int a_stream_ids[MAX_A_STREAMS];
40 } mpg_demuxer_t;
42 extern char* dvdsub_lang;
43 static int mpeg_pts_error=0;
44 off_t ps_probe = 0;
46 static int parse_psm(demuxer_t *demux, int len) {
47 unsigned char c, id, type;
48 unsigned int plen, prog_len, es_map_len;
49 mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
51 mp_dbg(MSGT_DEMUX,MSGL_V, "PARSE_PSM, len=%d\n", len);
52 if(! len || len > 1018)
53 return 0;
55 c = stream_read_char(demux->stream);
56 if(! (c & 0x80)) {
57 stream_skip(demux->stream, len - 1); //not yet valid, discard
58 return 0;
60 stream_skip(demux->stream, 1);
61 prog_len = stream_read_word(demux->stream); //length of program descriptors
62 stream_skip(demux->stream, prog_len); //.. that we ignore
63 es_map_len = stream_read_word(demux->stream); //length of elementary streams map
64 es_map_len = FFMIN(es_map_len, len - prog_len - 8); //sanity check
65 while(es_map_len > 0) {
66 type = stream_read_char(demux->stream);
67 id = stream_read_char(demux->stream);
68 if(id >= 0xB0 && id <= 0xEF && priv) {
69 int idoffset = id - 0xB0;
70 switch(type) {
71 case 0x1:
72 priv->es_map[idoffset] = VIDEO_MPEG1;
73 break;
74 case 0x2:
75 priv->es_map[idoffset] = VIDEO_MPEG2;
76 break;
77 case 0x3:
78 case 0x4:
79 priv->es_map[idoffset] = AUDIO_MP2;
80 break;
81 case 0x0f:
82 case 0x11:
83 priv->es_map[idoffset] = AUDIO_AAC;
84 break;
85 case 0x10:
86 priv->es_map[idoffset] = VIDEO_MPEG4;
87 break;
88 case 0x1b:
89 priv->es_map[idoffset] = VIDEO_H264;
90 break;
91 case 0x81:
92 priv->es_map[idoffset] = AUDIO_A52;
93 break;
95 mp_dbg(MSGT_DEMUX,MSGL_V, "PSM ES, id=0x%x, type=%x, stype: %x\n", id, type, priv->es_map[idoffset]);
97 plen = stream_read_word(demux->stream); //length of elementary stream descriptors
98 plen = FFMIN(plen, es_map_len); //sanity check
99 stream_skip(demux->stream, plen); //skip descriptors for now
100 es_map_len -= 4 + plen;
102 stream_skip(demux->stream, 4); //skip crc32
103 return 1;
106 // 500000 is a wild guess
107 #define TIMESTAMP_PROBE_LEN 500000
109 //MAX_PTS_DIFF_FOR_CONSECUTIVE denotes the maximum difference
110 //between two pts to consider them consecutive
111 //1.0 is a wild guess
112 #define MAX_PTS_DIFF_FOR_CONSECUTIVE 1.0
114 //returns the first pts found within TIME_STAMP_PROBE_LEN bytes after stream_pos in demuxer's stream.
115 //if no pts is found or an error occurs, -1.0 is returned.
116 //Packs are freed.
117 static float read_first_mpeg_pts_at_position(demuxer_t* demuxer, off_t stream_pos)
119 stream_t *s = demuxer->stream;
120 mpg_demuxer_t *mpg_d = demuxer->priv;
121 float pts = -1.0; //the pts to return;
122 float found_pts1; //the most recently found pts
123 float found_pts2; //the pts found before found_pts1
124 float found_pts3; //the pts found before found_pts2
125 int found = 0;
127 if(!mpg_d || stream_pos < 0)
128 return pts;
130 found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts;
131 stream_seek(s, stream_pos);
133 //We look for pts.
134 //However, we do not stop at the first found one, as timestamps may reset
135 //Therefore, we seek until we found three consecutive
136 //pts within MAX_PTS_DIFF_FOR_CONSECUTIVE.
138 while(found<3 && !s->eof
139 && (fabsf(found_pts2-found_pts1) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
140 && (fabsf(found_pts3-found_pts2) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
141 && (stream_tell(s) < stream_pos + TIMESTAMP_PROBE_LEN)
142 && ds_fill_buffer(demuxer->video))
144 if(mpg_d->last_pts != found_pts1)
146 if(!found)
147 found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts; //the most recently found pts
148 else
150 found_pts3 = found_pts2;
151 found_pts2 = found_pts1;
152 found_pts1 = mpg_d->last_pts;
154 found++;
158 if(found == 3) pts = found_pts3;
160 //clean up from searching of first pts;
161 ds_free_packs(demuxer->audio);
162 ds_free_packs(demuxer->video);
163 ds_free_packs(demuxer->sub);
165 return pts;
168 /// Open an mpg physical stream
169 static demuxer_t* demux_mpg_open(demuxer_t* demuxer) {
170 stream_t *s = demuxer->stream;
171 mpg_demuxer_t* mpg_d;
173 if (!ds_fill_buffer(demuxer->video)) return 0;
174 mpg_d = calloc(1,sizeof(mpg_demuxer_t));
175 if(mpg_d)
177 demuxer->priv = mpg_d;
178 mpg_d->last_pts = -1.0;
179 mpg_d->first_pts = -1.0;
181 //if seeking is allowed set has_valid_timestamps if appropriate
182 if(demuxer->seekable
183 && (demuxer->stream->type == STREAMTYPE_FILE
184 || demuxer->stream->type == STREAMTYPE_VCD)
185 && demuxer->movi_start != demuxer-> movi_end
188 //We seek to the beginning of the stream, to somewhere in the
189 //middle, and to the end of the stream, while remembering the pts
190 //at each of the three positions. With these pts, we check whether
191 //or not the pts are "linear enough" to justify seeking by the pts
192 //of the stream
194 //The position where the stream is now
195 off_t pos = stream_tell(s);
196 float first_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_start);
197 if(first_pts != -1.0)
199 float middle_pts = read_first_mpeg_pts_at_position(demuxer, (demuxer->movi_end + demuxer->movi_start)/2);
200 if(middle_pts != -1.0)
202 float final_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_end - TIMESTAMP_PROBE_LEN);
203 if(final_pts != -1.0)
205 // found proper first, middle, and final pts.
206 float proportion = (middle_pts-first_pts==0) ? -1 : (final_pts-middle_pts)/(middle_pts-first_pts);
207 // if they are linear enough set has_valid_timestamps
208 if((0.5 < proportion) && (proportion < 2))
210 mpg_d->first_pts = first_pts;
211 mpg_d->first_to_final_pts_len = final_pts - first_pts;
212 mpg_d->has_valid_timestamps = 1;
218 //Cleaning up from seeking in stream
219 demuxer->stream->eof=0;
220 demuxer->video->eof=0;
221 demuxer->audio->eof=0;
223 stream_seek(s,pos);
224 ds_fill_buffer(demuxer->video);
225 } // if ( demuxer->seekable )
226 } // if ( mpg_d )
227 return demuxer;
230 static void demux_close_mpg(demuxer_t* demuxer) {
231 mpg_demuxer_t* mpg_d = demuxer->priv;
232 if (mpg_d) free(mpg_d);
236 static unsigned long long read_mpeg_timestamp(stream_t *s,int c){
237 unsigned int d,e;
238 unsigned long long pts;
239 d=stream_read_word(s);
240 e=stream_read_word(s);
241 if( ((c&1)!=1) || ((d&1)!=1) || ((e&1)!=1) ){
242 ++mpeg_pts_error;
243 return 0; // invalid pts
245 pts=(((uint64_t)((c>>1)&7))<<30)|((d>>1)<<15)|(e>>1);
246 mp_dbg(MSGT_DEMUX,MSGL_DBG3," pts {%"PRIu64"}",pts);
247 return pts;
250 static void new_audio_stream(demuxer_t *demux, int aid){
251 if(!demux->a_streams[aid]){
252 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demux->priv;
253 sh_audio_t* sh_a;
254 new_sh_audio(demux,aid);
255 sh_a = (sh_audio_t*)demux->a_streams[aid];
256 switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id)
257 case 0x00: sh_a->format=0x50;break; // mpeg
258 case 0xA0: sh_a->format=0x10001;break; // dvd pcm
259 case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts
260 else sh_a->format=0x2000;break; // ac3
262 //evo files
263 if((aid & 0xC0) == 0xC0) sh_a->format=0x2000;
264 else if(aid >= 0x98 && aid <= 0x9f) sh_a->format=0x2001;
265 if (mpg_d) mpg_d->a_stream_ids[mpg_d->num_a_streams++] = aid;
267 if(demux->audio->id==-1) demux->audio->id=aid;
270 static int demux_mpg_read_packet(demuxer_t *demux,int id){
271 int d;
272 int len;
273 int set_pts=0; // !=0 iff pts has been set to a proper value
274 unsigned char c=0;
275 unsigned long long pts=0;
276 unsigned long long dts=0;
277 int l;
278 int pes_ext2_subid=-1;
279 double stream_pts = MP_NOPTS_VALUE;
280 demux_stream_t *ds=NULL;
281 demux_packet_t* dp;
282 mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
284 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_read_packet: %X\n",id);
286 // if(id==0x1F0){
287 // demux->synced=0; // force resync after 0x1F0
288 // return -1;
291 // if(id==0x1BA) packet_start_pos=stream_tell(demux->stream);
292 if((id<0x1BC || id>=0x1F0) && id != 0x1FD) return -1;
293 if(id==0x1BE) return -1; // padding stream
294 if(id==0x1BF) return -1; // private2
296 len=stream_read_word(demux->stream);
297 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"PACKET len=%d",len);
298 // if(len==62480){ demux->synced=0;return -1;} /* :) */
299 if(len==0 || len>MAX_PS_PACKETSIZE){
300 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS packet len: %d\n",len);
301 return -2; // invalid packet !!!!!!
304 mpeg_pts_error=0;
306 if(id==0x1BC) {
307 parse_psm(demux, len);
308 return 0;
311 while(len>0){ // Skip stuFFing bytes
312 c=stream_read_char(demux->stream);
313 --len;
314 if(c!=0xFF)break;
316 if((c>>6)==1){ // Read (skip) STD scale & size value
317 // printf(" STD_scale=%d",(c>>5)&1);
318 d=((c&0x1F)<<8)|stream_read_char(demux->stream);
319 len-=2;
320 // printf(" STD_size=%d",d);
321 c=stream_read_char(demux->stream);
323 // Read System-1 stream timestamps:
324 if((c>>4)==2){
325 pts=read_mpeg_timestamp(demux->stream,c);
326 set_pts=1;
327 len-=4;
328 } else
329 if((c>>4)==3){
330 pts=read_mpeg_timestamp(demux->stream,c);
331 c=stream_read_char(demux->stream);
332 if((c>>4)!=1) pts=0; //printf("{ERROR4}");
333 else set_pts = 1;
334 dts=read_mpeg_timestamp(demux->stream,c);
335 len-=4+1+4;
336 } else
337 if((c>>6)==2){
338 int pts_flags;
339 int hdrlen;
340 int parse_ext2;
341 // System-2 (.VOB) stream:
342 c=stream_read_char(demux->stream);
343 pts_flags=c>>6;
344 parse_ext2 = (id == 0x1FD) && ((c & 0x3F) == 1);
345 c=stream_read_char(demux->stream);
346 hdrlen=c;
347 len-=2;
348 mp_dbg(MSGT_DEMUX,MSGL_DBG3," hdrlen=%d (len=%d)",hdrlen,len);
349 if(hdrlen>len){ mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: invalid header length \n"); return -1;}
350 if(pts_flags==2 && hdrlen>=5){
351 c=stream_read_char(demux->stream);
352 pts=read_mpeg_timestamp(demux->stream,c);
353 set_pts=1;
354 len-=5;hdrlen-=5;
355 } else
356 if(pts_flags==3 && hdrlen>=10){
357 c=stream_read_char(demux->stream);
358 pts=read_mpeg_timestamp(demux->stream,c);
359 set_pts=1;
360 c=stream_read_char(demux->stream);
361 dts=read_mpeg_timestamp(demux->stream,c);
362 len-=10;hdrlen-=10;
364 len-=hdrlen;
365 if(parse_ext2 && hdrlen>=3) {
366 c=stream_read_char(demux->stream);
367 hdrlen--;
369 if((c & 0x0F) != 0x0F) {
370 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: pes_extension_flag2 not set, discarding pes packet\n");
371 return -1;
373 if(c & 0x80) { //pes_private_data_flag
374 if(hdrlen<16) {
375 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pes_private_data bytes: %d < 16, discarding pes packet\n", hdrlen);
376 return -1;
378 stream_skip(demux->stream, 16);
379 hdrlen-=16;
381 if(c & 0x40) { //pack_header_field_flag
382 int l = stream_read_char(demux->stream);
383 if(l < 0) //couldn't read from the stream?
384 return -1;
385 hdrlen--;
386 if(l < 0 || hdrlen < l) {
387 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pack_header bytes: hdrlen: %d < skip: %d, discarding pes packet\n",
388 hdrlen, l);
389 return -1;
391 stream_skip(demux->stream, l);
392 hdrlen-=l;
394 if(c & 0x20) { //program_packet_sequence_counter_flag
395 if(hdrlen < 2) {
396 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough program_packet bytes: hdrlen: %d, discarding pes packet\n", hdrlen);
397 return -1;
399 stream_skip(demux->stream, 2);
400 hdrlen-=2;
402 if(c & 0x10) {
403 //STD
404 stream_skip(demux->stream, 2);
405 hdrlen-=2;
407 c=stream_read_char(demux->stream); //pes_extension2 flag
408 hdrlen--;
409 if(c!=0x81) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown pes_extension2 format, len is > 1 \n"); return -1;}
410 c=stream_read_char(demux->stream); //pes_extension2 payload === substream id
411 hdrlen--;
412 if(c<0x55 || c>0x5F) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown vc1 substream_id: 0x%x \n", c); return -1;}
413 pes_ext2_subid=c;
415 if(hdrlen>0)
416 stream_skip(demux->stream,hdrlen); // skip header and stuffing bytes
418 if(id==0x1FD && pes_ext2_subid!=-1) {
419 //==== EVO VC1 STREAMS ===//
420 if(!demux->v_streams[pes_ext2_subid]) new_sh_video(demux,pes_ext2_subid);
421 if(demux->video->id==-1) demux->video->id=pes_ext2_subid;
422 if(demux->video->id==pes_ext2_subid){
423 ds=demux->video;
424 if(!ds->sh) ds->sh=demux->v_streams[pes_ext2_subid];
425 if(priv && ds->sh) {
426 sh_video_t *sh = (sh_video_t *)ds->sh;
427 sh->format = mmioFOURCC('W', 'V', 'C', '1');
431 //============== DVD Audio sub-stream ======================
432 if(id==0x1BD){
433 int aid, rawa52 = 0;
434 off_t tmppos;
435 unsigned int tmp;
437 tmppos = stream_tell(demux->stream);
438 tmp = stream_read_word(demux->stream);
439 stream_seek(demux->stream, tmppos);
440 /// vdr stores A52 without the 4 header bytes, so we have to check this condition first
441 if(tmp == 0x0B77) {
442 aid = 128;
443 rawa52 = 1;
445 else {
446 aid=stream_read_char(demux->stream);--len;
447 if(len<3) return -1; // invalid audio packet
450 // AID:
451 // 0x20..0x3F subtitle
452 // 0x80..0x87 and 0xC0..0xCF AC3 audio
453 // 0x88..0x8F and 0x98..0x9F DTS audio
454 // 0xA0..0xBF PCM audio
456 if((aid & 0xE0) == 0x20){
457 // subtitle:
458 aid&=0x1F;
460 if(!demux->s_streams[aid]){
461 sh_sub_t *sh = new_sh_sub(demux, aid);
462 if (sh) sh->type = 'v';
463 mp_msg(MSGT_DEMUX,MSGL_V,"==> Found subtitle: %d\n",aid);
466 if(demux->sub->id > -1)
467 demux->sub->id &= 0x1F;
468 if(!dvdsub_lang && demux->sub->id == -1)
469 demux->sub->id = aid;
470 if(demux->sub->id==aid){
471 ds=demux->sub;
473 } else if((aid >= 0x80 && aid <= 0x8F) || (aid >= 0x98 && aid <= 0xAF) || (aid >= 0xC0 && aid <= 0xCF)) {
475 // aid=128+(aid&0x7F);
476 // aid=0x80..0xBF
477 new_audio_stream(demux, aid);
478 if(demux->audio->id==aid){
479 int type;
480 ds=demux->audio;
481 if(!ds->sh) ds->sh=demux->a_streams[aid];
482 // READ Packet: Skip additional audio header data:
483 if(!rawa52) {
484 c=stream_read_char(demux->stream);//num of frames
485 type=stream_read_char(demux->stream);//startpos hi
486 type=(type<<8)|stream_read_char(demux->stream);//startpos lo
487 // printf("\r[%02X][%04X]",c,type);
488 len-=3;
490 if((aid&0xE0)==0xA0 && len>=3){
491 unsigned char* hdr;
492 // save audio header as codecdata!
493 if(!((sh_audio_t*)(ds->sh))->codecdata_len){
494 ((sh_audio_t*)(ds->sh))->codecdata=malloc(3);
495 ((sh_audio_t*)(ds->sh))->codecdata_len=3;
497 hdr=((sh_audio_t*)(ds->sh))->codecdata;
498 // read LPCM header:
499 // emphasis[1], mute[1], rvd[1], frame number[5]:
500 hdr[0]=stream_read_char(demux->stream);
501 // printf(" [%01X:%02d]",c>>5,c&31);
502 // quantization[2],freq[2],rvd[1],channels[3]
503 hdr[1]=stream_read_char(demux->stream);
504 // printf("[%01X:%01X] ",c>>4,c&15);
505 // dynamic range control (0x80=off):
506 hdr[2]=stream_read_char(demux->stream);
507 // printf("[%02X] ",c);
508 len-=3;
509 if(len<=0) mp_msg(MSGT_DEMUX,MSGL_V,"End of packet while searching for PCM header\n");
511 // printf(" \n");
512 } // if(demux->audio->id==aid)
514 } else mp_msg(MSGT_DEMUX,MSGL_V,"Unknown 0x1BD substream: 0x%02X \n",aid);
515 } //if(id==0x1BD)
516 } else {
517 if(c!=0x0f){
518 mp_msg(MSGT_DEMUX,MSGL_V," {ERROR5,c=%d} \n",c);
519 return -1; // invalid packet !!!!!!
522 if(mpeg_pts_error) mp_msg(MSGT_DEMUX,MSGL_V," {PTS_err:%d} \n",mpeg_pts_error);
523 mp_dbg(MSGT_DEMUX,MSGL_DBG3," => len=%d\n",len);
525 // if(len<=0 || len>MAX_PS_PACKETSIZE) return -1; // Invalid packet size
526 if(len<=0 || len>MAX_PS_PACKETSIZE){
527 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS data len: %d\n",len);
528 return -1; // invalid packet !!!!!!
531 if(id>=0x1C0 && id<=0x1DF){
532 // mpeg audio
533 int aid=id-0x1C0;
534 new_audio_stream(demux, aid);
535 if(demux->audio->id==aid){
536 ds=demux->audio;
537 if(!ds->sh) ds->sh=demux->a_streams[aid];
538 if(priv && ds->sh) {
539 sh_audio_t *sh = (sh_audio_t *)ds->sh;
540 if(priv->es_map[id - 0x1B0])
541 sh->format = priv->es_map[id - 0x1B0];
542 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
545 } else
546 if(id>=0x1E0 && id<=0x1EF){
547 // mpeg video
548 int aid=id-0x1E0;
549 if(!demux->v_streams[aid]) new_sh_video(demux,aid);
550 if(demux->video->id==-1) demux->video->id=aid;
551 if(demux->video->id==aid){
552 ds=demux->video;
553 if(!ds->sh) ds->sh=demux->v_streams[aid];
554 if(priv && ds->sh) {
555 sh_video_t *sh = (sh_video_t *)ds->sh;
556 if(priv->es_map[id - 0x1B0]) {
557 sh->format = priv->es_map[id - 0x1B0];
558 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
564 if(ds){
565 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Read %d data bytes from packet %04X\n",len,id);
566 // printf("packet start = 0x%X \n",stream_tell(demux->stream)-packet_start_pos);
568 dp=new_demux_packet(len);
569 if(!dp) {
570 mp_dbg(MSGT_DEMUX,MSGL_ERR,"DEMUX_MPG ERROR: couldn't create demux_packet(%d bytes)\n",len);
571 stream_skip(demux->stream,len);
572 return 0;
574 l = stream_read(demux->stream,dp->buffer,len);
575 if(l<len)
576 resize_demux_packet(dp, l);
577 len = l;
578 if(set_pts)
579 dp->pts=pts/90000.0f;
580 dp->pos=demux->filepos;
582 workaround:
583 set dp->stream_pts only when feeding the video stream, or strangely interleaved files
584 (such as SWIII) will show strange alternations in the stream time, wildly going
585 back and forth
587 if(ds == demux->video && stream_control(demux->stream, STREAM_CTRL_GET_CURRENT_TIME,(void *)&stream_pts)!=STREAM_UNSUPPORTED)
588 dp->stream_pts = stream_pts;
589 ds_add_packet(ds,dp);
590 if (demux->priv && set_pts) ((mpg_demuxer_t*)demux->priv)->last_pts = pts/90000.0f;
591 // if(ds==demux->sub) parse_dvdsub(ds->last->buffer,ds->last->len);
592 return 1;
594 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Skipping %d data bytes from packet %04X\n",len,id);
595 if(len<=2356) stream_skip(demux->stream,len);
596 return 0;
599 static int num_elementary_packets100=0;
600 static int num_elementary_packets101=0;
601 static int num_elementary_packets12x=0;
602 static int num_elementary_packets1B6=0;
603 static int num_elementary_packetsPES=0;
604 static int num_h264_slice=0; //combined slice
605 static int num_h264_dpa=0; //DPA Slice
606 static int num_h264_dpb=0; //DPB Slice
607 static int num_h264_dpc=0; //DPC Slice
608 static int num_h264_idr=0; //IDR Slice
609 static int num_h264_sps=0;
610 static int num_h264_pps=0;
612 static int num_mp3audio_packets=0;
614 static void clear_stats(void)
616 num_elementary_packets100=0;
617 num_elementary_packets101=0;
618 num_elementary_packets1B6=0;
619 num_elementary_packets12x=0;
620 num_elementary_packetsPES=0;
621 num_h264_slice=0; //combined slice
622 num_h264_dpa=0; //DPA Slice
623 num_h264_dpb=0; //DPB Slice
624 num_h264_dpc=0; //DPC Slice
625 num_h264_idr=0; //IDR Slice
626 num_h264_sps=0;
627 num_h264_pps=0;
628 num_mp3audio_packets=0;
631 //assumes demuxer->synced < 2
632 static inline void update_stats(int head)
634 if(head==0x1B6) ++num_elementary_packets1B6;
635 else if(head==0x100) ++num_elementary_packets100;
636 else if(head==0x101) ++num_elementary_packets101;
637 else if(head==0x1BD || (0x1C0<=head && head<=0x1EF))
638 num_elementary_packetsPES++;
639 else if(head>=0x120 && head<=0x12F) ++num_elementary_packets12x;
640 if(head>=0x100 && head<0x1B0)
642 if((head&~0x60) == 0x101) ++num_h264_slice;
643 else if((head&~0x60) == 0x102) ++num_h264_dpa;
644 else if((head&~0x60) == 0x103) ++num_h264_dpb;
645 else if((head&~0x60) == 0x104) ++num_h264_dpc;
646 else if((head&~0x60) == 0x105 && head != 0x105) ++num_h264_idr;
647 else if((head&~0x60) == 0x107 && head != 0x107) ++num_h264_sps;
648 else if((head&~0x60) == 0x108 && head != 0x108) ++num_h264_pps;
652 static int demux_mpg_probe(demuxer_t *demuxer) {
653 int pes=1;
654 int tmp;
655 off_t tmppos;
656 int file_format = DEMUXER_TYPE_UNKNOWN;
658 tmppos=stream_tell(demuxer->stream);
659 tmp=stream_read_dword(demuxer->stream);
660 if(tmp==0x1E0 || tmp==0x1C0) {
661 tmp=stream_read_word(demuxer->stream);
662 if(tmp>1 && tmp<=2048) pes=0; // demuxer->synced=3; // PES...
664 stream_seek(demuxer->stream,tmppos);
666 clear_stats();
668 if(demux_mpg_open(demuxer))
669 file_format=DEMUXER_TYPE_MPEG_PS;
670 else {
671 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",
672 num_elementary_packets100,num_elementary_packets101,
673 num_elementary_packets1B6,num_elementary_packets12x,
674 num_h264_slice, num_h264_dpa,
675 num_h264_dpb, num_h264_dpc=0,
676 num_h264_idr, num_h264_sps=0,
677 num_h264_pps,
678 num_elementary_packetsPES,num_mp3audio_packets, demuxer->synced);
680 //MPEG packet stats: p100: 458 p101: 458 PES: 0 MP3: 1103 (.m2v)
681 if(num_mp3audio_packets>50 && num_mp3audio_packets>2*num_elementary_packets100
682 && abs(num_elementary_packets100-num_elementary_packets101)>2)
683 return file_format;
685 // some hack to get meaningfull error messages to our unhappy users:
686 if(num_elementary_packets100>=2 && num_elementary_packets101>=2 &&
687 abs(num_elementary_packets101+8-num_elementary_packets100)<16) {
688 if(num_elementary_packetsPES>=4 && num_elementary_packetsPES>=num_elementary_packets100-4) {
689 return file_format;
691 file_format=DEMUXER_TYPE_MPEG_ES; // <-- hack is here :)
692 } else
693 // fuzzy mpeg4-es detection. do NOT enable without heavy testing of mpeg formats detection!
694 if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
695 num_elementary_packetsPES==0 && num_elementary_packets100<=num_elementary_packets12x &&
696 demuxer->synced<2) {
697 file_format=DEMUXER_TYPE_MPEG4_ES;
698 } else
699 // fuzzy h264-es detection. do NOT enable without heavy testing of mpeg formats detection!
700 if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
701 /* FIXME num_h264_sps>=1 && */ num_h264_pps>=1 && num_h264_idr>=1 &&
702 num_elementary_packets1B6==0 && num_elementary_packetsPES==0 &&
703 demuxer->synced<2) {
704 file_format=DEMUXER_TYPE_H264_ES;
705 } else
707 if(demuxer->synced==2)
708 mp_msg(MSGT_DEMUXER,MSGL_ERR,"MPEG: " MSGTR_MissingVideoStreamBug);
709 else
710 mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_NotSystemStream);
713 //FIXME this shouldn't be necessary
714 stream_seek(demuxer->stream,tmppos);
715 return file_format;
718 static int demux_mpg_es_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
719 // Elementary video stream
720 if(demux->stream->eof) return 0;
721 demux->filepos=stream_tell(demux->stream);
722 ds_read_packet(demux->video,demux->stream,STREAM_BUFFER_SIZE,0,demux->filepos,0);
723 return 1;
727 * \brief discard until 0x100 header and return a filled buffer
728 * \param b buffer-end pointer
729 * \param pos current pos in stream, negative since b points to end of buffer
730 * \param s stream to read from
731 * \return new position, differs from original pos when eof hit and thus
732 * b was modified to point to the new end of buffer
734 static int find_end(unsigned char **b, int pos, stream_t *s) {
735 register int state = 0xffffffff;
736 unsigned char *buf = *b;
737 int start = pos;
738 int read, unused;
739 // search already read part
740 while (state != 0x100 && pos) {
741 state = state << 8 | buf[pos++];
743 // continue search in stream
744 while (state != 0x100) {
745 register int c = stream_read_char(s);
746 if (c < 0) break;
747 state = state << 8 | c;
749 // modify previous header (from 0x1bc or 0x1bf to 0x100)
750 buf[start++] = 0;
751 // copy remaining buffer part to current pos
752 memmove(&buf[start], &buf[pos], -pos);
753 unused = start + -pos; // -unused bytes in buffer
754 read = stream_read(s, &buf[unused], -unused);
755 unused += read;
756 // fix buffer so it ends at pos == 0 (eof case)
757 *b = &buf[unused];
758 start -= unused;
759 return start;
763 * This format usually uses an insane bitrate, which makes this function
764 * performance-critical!
765 * Be sure to benchmark any changes with different compiler versions.
767 static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
768 demux_packet_t *pack;
769 int len;
770 demux->filepos = stream_tell(demux->stream);
771 pack = new_demux_packet(STREAM_BUFFER_SIZE);
772 len = stream_read(demux->stream, pack->buffer, STREAM_BUFFER_SIZE);
773 if (len <= 0)
775 free_demux_packet(pack);
776 return 0;
779 register uint32_t state = (uint32_t)demux->priv;
780 register int pos = -len;
781 unsigned char *buf = &pack->buffer[len];
782 do {
783 state = state << 8 | buf[pos];
784 if (unlikely((state | 3) == 0x1bf))
785 pos = find_end(&buf, pos, demux->stream);
786 } while (++pos < 0);
787 demux->priv = (void *)state;
788 len = buf - pack->buffer;
790 if (len < STREAM_BUFFER_SIZE)
791 resize_demux_packet(pack, len);
792 ds_add_packet(ds, pack);
793 return 1;
796 int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
797 unsigned int head=0;
798 int skipped=0;
799 int max_packs=256; // 512kbyte
800 int ret=0;
802 // System stream
804 demux->filepos=stream_tell(demux->stream);
805 #if 1
806 //lame workaround: this is needed to show the progress bar when playing dvdnav://
807 //(ths poor guy doesn't know teh length of the stream at startup)
808 demux->movi_end = demux->stream->end_pos;
809 #endif
810 head=stream_read_dword(demux->stream);
811 if((head&0xFFFFFF00)!=0x100){
812 // sync...
813 demux->filepos-=skipped;
814 while(1){
815 int c=stream_read_char(demux->stream);
816 if(c<0) break; //EOF
817 head<<=8;
818 if(head!=0x100){
819 head|=c;
820 if(mp_check_mp3_header(head)) ++num_mp3audio_packets;
821 ++skipped; //++demux->filepos;
822 continue;
824 head|=c;
825 break;
827 demux->filepos+=skipped;
829 if(stream_eof(demux->stream)) break;
830 // sure: head=0x000001XX
831 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"*** head=0x%X\n",head);
832 if(demux->synced==0){
833 if(head==0x1BA) demux->synced=1; //else
834 // if(head==0x1BD || (head>=0x1C0 && head<=0x1EF)) demux->synced=3; // PES?
835 } else
836 if(demux->synced==1){
837 if(head==0x1BB || head==0x1BD || (head>=0x1C0 && head<=0x1EF)){
838 demux->synced=2;
839 mp_msg(MSGT_DEMUX,MSGL_V,"system stream synced at 0x%"PRIX64" (%"PRId64")!\n",(int64_t)demux->filepos,(int64_t)demux->filepos);
840 num_elementary_packets100=0; // requires for re-sync!
841 num_elementary_packets101=0; // requires for re-sync!
842 } else demux->synced=0;
843 } // else
844 if(demux->synced>=2){
845 ret=demux_mpg_read_packet(demux,head);
846 if(!ret)
847 if(--max_packs==0){
848 demux->stream->eof=1;
849 mp_msg(MSGT_DEMUX,MSGL_ERR,MSGTR_DoesntContainSelectedStream);
850 return 0;
852 if(demux->synced==3) demux->synced=(ret==1)?2:0; // PES detect
853 } else {
854 update_stats(head);
855 if(head>=0x100 && head<0x1B0)
856 mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... elementary video packet found: %03X\n",head);
857 else if((head>=0x1C0 && head<0x1F0) || head==0x1BD)
858 mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... PES packet found: %03X\n",head);
860 if(((num_elementary_packets100>50 && num_elementary_packets101>50) ||
861 (num_elementary_packetsPES>50)) && skipped>4000000){
862 mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be ES/PES stream...\n");
863 demux->stream->eof=1;
864 break;
866 if(num_mp3audio_packets>100 && num_elementary_packets100<10){
867 mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be MP3 stream...\n");
868 demux->stream->eof=1;
869 break;
872 } while(ret!=1);
873 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux: %d bad bytes skipped\n",skipped);
874 if(demux->stream->eof){
875 mp_msg(MSGT_DEMUX,MSGL_V,"MPEG Stream reached EOF\n");
876 return 0;
878 return 1;
881 extern void skip_audio_frame(sh_audio_t *sh_audio);
883 void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,float audio_delay, int flags){
884 demux_stream_t *d_audio=demuxer->audio;
885 demux_stream_t *d_video=demuxer->video;
886 sh_audio_t *sh_audio=d_audio->sh;
887 sh_video_t *sh_video=d_video->sh;
888 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
889 int precision = 1;
890 float oldpts = 0;
891 off_t oldpos = demuxer->filepos;
892 float newpts = 0;
893 off_t newpos = (flags & 1) ? demuxer->movi_start : oldpos;
895 if(mpg_d)
896 oldpts = mpg_d->last_pts;
897 newpts = (flags & 1) ? 0.0 : oldpts;
898 //================= seek in MPEG ==========================
899 //calculate the pts to seek to
900 if(flags & 2) {
901 if (mpg_d && mpg_d->first_to_final_pts_len > 0.0)
902 newpts += mpg_d->first_to_final_pts_len * rel_seek_secs;
903 else
904 newpts += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * oldpts / oldpos;
905 } else
906 newpts += rel_seek_secs;
907 if (newpts < 0) newpts = 0;
909 if(flags&2){
910 // float seek 0..1
911 newpos+=(demuxer->movi_end-demuxer->movi_start)*rel_seek_secs;
912 } else {
913 // time seek (secs)
914 if (mpg_d && mpg_d->has_valid_timestamps) {
915 if (mpg_d->first_to_final_pts_len > 0.0)
916 newpos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / mpg_d->first_to_final_pts_len;
917 else if (oldpts > 0.0)
918 newpos += rel_seek_secs * (oldpos - demuxer->movi_start) / oldpts;
919 } else if(!sh_video || !sh_video->i_bps) // unspecified or VBR
920 newpos+=2324*75*rel_seek_secs; // 174.3 kbyte/sec
921 else
922 newpos+=sh_video->i_bps*rel_seek_secs;
925 while (1) {
926 if(newpos<demuxer->movi_start){
927 if(demuxer->stream->type!=STREAMTYPE_VCD) demuxer->movi_start=0; // for VCD
928 if(newpos<demuxer->movi_start) newpos=demuxer->movi_start;
931 stream_seek(demuxer->stream,newpos);
933 // re-sync video:
934 videobuf_code_len=0; // reset ES stream buffer
936 ds_fill_buffer(d_video);
937 if(sh_audio){
938 ds_fill_buffer(d_audio);
941 while(1){
942 int i;
943 if(sh_audio && !d_audio->eof && d_video->pts && d_audio->pts){
944 float a_pts=d_audio->pts;
945 a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
946 if(d_video->pts>a_pts){
947 skip_audio_frame(sh_audio); // sync audio
948 continue;
951 if(!sh_video) break;
952 i=sync_video_packet(d_video);
953 if(sh_video->format == mmioFOURCC('W', 'V', 'C', '1')) {
954 if(i==0x10E || i==0x10F) //entry point or sequence header
955 break;
956 } else
957 if(sh_video->format == 0x10000004) { //mpeg4
958 if(i==0x1B6) { //vop (frame) startcode
959 int pos = videobuf_len;
960 if(!read_video_packet(d_video)) break; // EOF
961 if((videobuffer[pos+4] & 0x3F) == 0) break; //I-frame
963 } else if(sh_video->format == 0x10000005){ //h264
964 if((i & ~0x60) == 0x105) break;
965 } else { //default mpeg1/2
966 if(i==0x1B3 || i==0x1B8) break; // found it!
968 if(!i || !skip_video_packet(d_video)) break; // EOF?
970 if(!mpg_d)
971 break;
972 if (!precision || abs(newpts - mpg_d->last_pts) < 0.5 || (mpg_d->last_pts == oldpts)) break;
973 if ((newpos - oldpos) * (mpg_d->last_pts - oldpts) < 0) { // invalid timestamps
974 mpg_d->has_valid_timestamps = 0;
975 break;
977 precision--;
978 //prepare another seek because we are off by more than 0.5s
979 if(mpg_d) {
980 newpos += (newpts - mpg_d->last_pts) * (newpos - oldpos) / (mpg_d->last_pts - oldpts);
981 ds_free_packs(d_audio);
982 ds_free_packs(d_video);
983 ds_free_packs(demuxer->sub);
984 demuxer->stream->eof=0; // clear eof flag
985 d_video->eof=0;
986 d_audio->eof=0;
991 int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){
992 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
994 switch(cmd) {
995 case DEMUXER_CTRL_GET_TIME_LENGTH:
996 if(stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, arg) != STREAM_UNSUPPORTED) {
997 mp_msg(MSGT_DEMUXER,MSGL_DBG2,"\r\nDEMUX_MPG_CTRL, (%.3lf)\r\n", *((double*)arg));
998 return DEMUXER_CTRL_GUESS;
1000 if (mpg_d && mpg_d->has_valid_timestamps) {
1001 *((double *)arg)=(double)mpg_d->first_to_final_pts_len;
1002 return DEMUXER_CTRL_OK;
1004 return DEMUXER_CTRL_DONTKNOW;
1006 case DEMUXER_CTRL_GET_PERCENT_POS:
1007 if (mpg_d && mpg_d->has_valid_timestamps && mpg_d->first_to_final_pts_len > 0.0) {
1008 *((int *)arg)=(int)(100 * (mpg_d->last_pts-mpg_d->first_pts) / mpg_d->first_to_final_pts_len);
1009 return DEMUXER_CTRL_OK;
1011 return DEMUXER_CTRL_DONTKNOW;
1013 case DEMUXER_CTRL_SWITCH_AUDIO:
1014 if(! (mpg_d && mpg_d->num_a_streams > 1 && demuxer->audio && demuxer->audio->sh))
1015 return DEMUXER_CTRL_NOTIMPL;
1016 else {
1017 demux_stream_t *d_audio = demuxer->audio;
1018 sh_audio_t *sh_audio = d_audio->sh;
1019 sh_audio_t *sh_a = sh_audio;
1020 int i;
1021 if(!sh_audio)
1022 return DEMUXER_CTRL_NOTIMPL;
1023 if (*((int*)arg) < 0)
1025 for (i = 0; i < mpg_d->num_a_streams; i++) {
1026 if (d_audio->id == mpg_d->a_stream_ids[i]) break;
1028 i = (i+1) % mpg_d->num_a_streams;
1029 sh_a = (sh_audio_t*)demuxer->a_streams[mpg_d->a_stream_ids[i]];
1031 else {
1032 for (i = 0; i < mpg_d->num_a_streams; i++)
1033 if (*((int*)arg) == mpg_d->a_stream_ids[i]) break;
1034 if (i < mpg_d->num_a_streams)
1035 sh_a = (sh_audio_t*)demuxer->a_streams[*((int*)arg)];
1037 if (i < mpg_d->num_a_streams && d_audio->id != mpg_d->a_stream_ids[i]) {
1038 d_audio->id = mpg_d->a_stream_ids[i];
1039 d_audio->sh = sh_a;
1040 ds_free_packs(d_audio);
1043 *((int*)arg) = demuxer->audio->id;
1044 return DEMUXER_CTRL_OK;
1046 default:
1047 return DEMUXER_CTRL_NOTIMPL;
1052 static int demux_mpg_pes_probe(demuxer_t *demuxer) {
1053 demuxer->synced = 3;
1054 return (demux_mpg_probe(demuxer) == DEMUXER_TYPE_MPEG_PS) ? DEMUXER_TYPE_MPEG_PES : 0;
1058 static demuxer_t* demux_mpg_es_open(demuxer_t* demuxer)
1060 sh_video_t *sh_video=NULL;
1062 demuxer->audio->sh = NULL; // ES streams has no audio channel
1063 demuxer->video->sh = new_sh_video(demuxer,0); // create dummy video stream header, id=0
1064 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1066 return demuxer;
1069 static demuxer_t *demux_mpg_gxf_open(demuxer_t *demuxer) {
1070 demuxer->audio->sh = NULL;
1071 demuxer->video->sh = new_sh_video(demuxer,0);
1072 ((sh_video_t *)demuxer->video->sh)->ds = demuxer->video;
1073 demuxer->priv = (void *) 0xffffffff;
1074 return demuxer;
1077 static demuxer_t* demux_mpg_ps_open(demuxer_t* demuxer)
1079 sh_audio_t *sh_audio=NULL;
1080 sh_video_t *sh_video=NULL;
1082 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1084 if(demuxer->audio->id!=-2) {
1085 if(!ds_fill_buffer(demuxer->audio)){
1086 mp_msg(MSGT_DEMUXER,MSGL_INFO,"MPEG: " MSGTR_MissingAudioStream);
1087 demuxer->audio->sh=NULL;
1088 } else {
1089 sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
1093 if(!sh_video->format && ps_probe > 0) {
1094 int head;
1095 off_t pos = stream_tell(demuxer->stream);
1097 clear_stats();
1098 do {
1099 head=sync_video_packet(demuxer->video);
1100 if(!head) break;
1101 update_stats(head);
1102 skip_video_packet(demuxer->video);
1103 } while(stream_tell(demuxer->stream) < pos + ps_probe && !demuxer->stream->eof);
1105 ds_free_packs(demuxer->video);
1106 demuxer->stream->eof=0;
1107 stream_seek(demuxer->stream, pos);
1108 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",
1109 num_elementary_packets100, num_elementary_packets101,
1110 num_elementary_packets1B6, num_elementary_packets12x,
1111 num_h264_slice, num_h264_dpa, num_h264_dpb, num_h264_dpc,
1112 num_h264_idr, num_h264_sps, num_h264_pps);
1114 if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
1115 num_elementary_packets100<=num_elementary_packets12x)
1116 sh_video->format = 0x10000004;
1117 else if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
1118 num_h264_sps>=1 && num_h264_pps>=1 && num_h264_idr>=1 &&
1119 num_elementary_packets1B6==0)
1120 sh_video->format = 0x10000005;
1121 else sh_video->format = 0x10000002;
1124 return demuxer;
1128 demuxer_desc_t demuxer_desc_mpeg_ps = {
1129 "MPEG PS demuxer",
1130 "mpegps",
1131 "MPEG-PS",
1132 "Arpi?",
1133 "Mpeg",
1134 DEMUXER_TYPE_MPEG_PS,
1135 0, // unsafe autodetect
1136 demux_mpg_probe,
1137 demux_mpg_fill_buffer,
1138 demux_mpg_ps_open,
1139 demux_close_mpg,
1140 demux_seek_mpg,
1141 demux_mpg_control,
1145 demuxer_desc_t demuxer_desc_mpeg_pes = {
1146 "MPEG PES demuxer",
1147 "mpegpes",
1148 "MPEG-PES",
1149 "Arpi?",
1150 "Mpeg",
1151 DEMUXER_TYPE_MPEG_PES,
1152 0, // unsafe autodetect
1153 demux_mpg_pes_probe,
1154 demux_mpg_fill_buffer,
1155 demux_mpg_ps_open,
1156 demux_close_mpg,
1157 demux_seek_mpg,
1158 demux_mpg_control,
1162 demuxer_desc_t demuxer_desc_mpeg_gxf = {
1163 "MPEG ES in GXF demuxer",
1164 "mpeggxf",
1165 "MPEG-ES in GXF",
1166 "Reimar Doeffinger",
1167 "Mpeg",
1168 DEMUXER_TYPE_MPEG_GXF,
1169 0, // hack autodetection
1170 NULL,
1171 demux_mpg_gxf_fill_buffer,
1172 demux_mpg_gxf_open,
1173 NULL,
1174 NULL,
1175 NULL
1178 demuxer_desc_t demuxer_desc_mpeg_es = {
1179 "MPEG ES demuxer",
1180 "mpeges",
1181 "MPEG-ES",
1182 "Arpi?",
1183 "Mpeg",
1184 DEMUXER_TYPE_MPEG_ES,
1185 0, // hack autodetection
1186 NULL,
1187 demux_mpg_es_fill_buffer,
1188 demux_mpg_es_open,
1189 demux_close_mpg,
1190 demux_seek_mpg,
1191 demux_mpg_control,
1195 demuxer_desc_t demuxer_desc_mpeg4_es = {
1196 "MPEG4 ES demuxer",
1197 "mpeg4es",
1198 "MPEG-ES",
1199 "Arpi?",
1200 "Mpeg",
1201 DEMUXER_TYPE_MPEG4_ES,
1202 0, // hack autodetection
1203 NULL,
1204 demux_mpg_es_fill_buffer,
1205 demux_mpg_es_open,
1206 demux_close_mpg,
1207 demux_seek_mpg,
1208 demux_mpg_control,
1212 demuxer_desc_t demuxer_desc_h264_es = {
1213 "H.264 ES demuxer",
1214 "h264es",
1215 "H264-ES",
1216 "Arpi?",
1217 "Mpeg",
1218 DEMUXER_TYPE_H264_ES,
1219 0, // hack autodetection
1220 NULL,
1221 demux_mpg_es_fill_buffer,
1222 demux_mpg_es_open,
1223 demux_close_mpg,
1224 demux_seek_mpg,
1225 demux_mpg_control,