Files should be opened in binary mode on OS/2.
[mplayer/glamo.git] / libmpdemux / demux_mpg.c
blob09bcd95178d347667a1e72e7ee9fefaa5e06bea2
1 /*
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.
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <math.h>
27 #include "config.h"
28 #include "mp_msg.h"
29 #include "help_mp.h"
31 #include "stream/stream.h"
32 #include "demuxer.h"
33 #include "parse_es.h"
34 #include "stheader.h"
35 #include "mp3_hdr.h"
37 //#define MAX_PS_PACKETSIZE 2048
38 #define MAX_PS_PACKETSIZE (224*1024)
40 #define UNKNOWN 0
41 #define VIDEO_MPEG1 0x10000001
42 #define VIDEO_MPEG2 0x10000002
43 #define VIDEO_MPEG4 0x10000004
44 #define VIDEO_H264 0x10000005
45 #define AUDIO_MP2 0x50
46 #define AUDIO_A52 0x2000
47 #define AUDIO_LPCM_BE 0x10001
48 #define AUDIO_AAC mmioFOURCC('M', 'P', '4', 'A')
50 typedef struct mpg_demuxer {
51 float last_pts;
52 float first_pts; // first pts found in stream
53 float first_to_final_pts_len; // difference between final pts and first pts
54 int has_valid_timestamps; // !=0 iff time stamps look linear
55 // (not necessarily starting with 0)
56 unsigned int es_map[0x40]; //es map of stream types (associated to the pes id) from 0xb0 to 0xef
57 int num_a_streams;
58 int a_stream_ids[MAX_A_STREAMS];
59 } mpg_demuxer_t;
61 extern char* dvdsub_lang;
62 static int mpeg_pts_error=0;
63 off_t ps_probe = 0;
65 static int parse_psm(demuxer_t *demux, int len) {
66 unsigned char c, id, type;
67 unsigned int plen, prog_len, es_map_len;
68 mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
70 mp_dbg(MSGT_DEMUX,MSGL_V, "PARSE_PSM, len=%d\n", len);
71 if(! len || len > 1018)
72 return 0;
74 c = stream_read_char(demux->stream);
75 if(! (c & 0x80)) {
76 stream_skip(demux->stream, len - 1); //not yet valid, discard
77 return 0;
79 stream_skip(demux->stream, 1);
80 prog_len = stream_read_word(demux->stream); //length of program descriptors
81 stream_skip(demux->stream, prog_len); //.. that we ignore
82 es_map_len = stream_read_word(demux->stream); //length of elementary streams map
83 es_map_len = FFMIN(es_map_len, len - prog_len - 8); //sanity check
84 while(es_map_len > 0) {
85 type = stream_read_char(demux->stream);
86 id = stream_read_char(demux->stream);
87 if(id >= 0xB0 && id <= 0xEF && priv) {
88 int idoffset = id - 0xB0;
89 switch(type) {
90 case 0x1:
91 priv->es_map[idoffset] = VIDEO_MPEG1;
92 break;
93 case 0x2:
94 priv->es_map[idoffset] = VIDEO_MPEG2;
95 break;
96 case 0x3:
97 case 0x4:
98 priv->es_map[idoffset] = AUDIO_MP2;
99 break;
100 case 0x0f:
101 case 0x11:
102 priv->es_map[idoffset] = AUDIO_AAC;
103 break;
104 case 0x10:
105 priv->es_map[idoffset] = VIDEO_MPEG4;
106 break;
107 case 0x1b:
108 priv->es_map[idoffset] = VIDEO_H264;
109 break;
110 case 0x81:
111 priv->es_map[idoffset] = AUDIO_A52;
112 break;
114 mp_dbg(MSGT_DEMUX,MSGL_V, "PSM ES, id=0x%x, type=%x, stype: %x\n", id, type, priv->es_map[idoffset]);
116 plen = stream_read_word(demux->stream); //length of elementary stream descriptors
117 plen = FFMIN(plen, es_map_len); //sanity check
118 stream_skip(demux->stream, plen); //skip descriptors for now
119 es_map_len -= 4 + plen;
121 stream_skip(demux->stream, 4); //skip crc32
122 return 1;
125 // 500000 is a wild guess
126 #define TIMESTAMP_PROBE_LEN 500000
128 //MAX_PTS_DIFF_FOR_CONSECUTIVE denotes the maximum difference
129 //between two pts to consider them consecutive
130 //1.0 is a wild guess
131 #define MAX_PTS_DIFF_FOR_CONSECUTIVE 1.0
133 //returns the first pts found within TIME_STAMP_PROBE_LEN bytes after stream_pos in demuxer's stream.
134 //if no pts is found or an error occurs, -1.0 is returned.
135 //Packs are freed.
136 static float read_first_mpeg_pts_at_position(demuxer_t* demuxer, off_t stream_pos)
138 stream_t *s = demuxer->stream;
139 mpg_demuxer_t *mpg_d = demuxer->priv;
140 float pts = -1.0; //the pts to return;
141 float found_pts1; //the most recently found pts
142 float found_pts2; //the pts found before found_pts1
143 float found_pts3; //the pts found before found_pts2
144 int found = 0;
146 if(!mpg_d || stream_pos < 0)
147 return pts;
149 found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts;
150 stream_seek(s, stream_pos);
152 //We look for pts.
153 //However, we do not stop at the first found one, as timestamps may reset
154 //Therefore, we seek until we found three consecutive
155 //pts within MAX_PTS_DIFF_FOR_CONSECUTIVE.
157 while(found<3 && !s->eof
158 && (fabsf(found_pts2-found_pts1) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
159 && (fabsf(found_pts3-found_pts2) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
160 && (stream_tell(s) < stream_pos + TIMESTAMP_PROBE_LEN)
161 && ds_fill_buffer(demuxer->video))
163 if(mpg_d->last_pts != found_pts1)
165 if(!found)
166 found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts; //the most recently found pts
167 else
169 found_pts3 = found_pts2;
170 found_pts2 = found_pts1;
171 found_pts1 = mpg_d->last_pts;
173 found++;
177 if(found == 3) pts = found_pts3;
179 //clean up from searching of first pts;
180 demux_flush(demuxer);
182 return pts;
185 /// Open an mpg physical stream
186 static demuxer_t* demux_mpg_open(demuxer_t* demuxer) {
187 stream_t *s = demuxer->stream;
188 mpg_demuxer_t* mpg_d;
190 if (!ds_fill_buffer(demuxer->video)) return 0;
191 mpg_d = calloc(1,sizeof(mpg_demuxer_t));
192 if(mpg_d)
194 demuxer->priv = mpg_d;
195 mpg_d->last_pts = -1.0;
196 mpg_d->first_pts = -1.0;
198 //if seeking is allowed set has_valid_timestamps if appropriate
199 if(demuxer->seekable
200 && (demuxer->stream->type == STREAMTYPE_FILE
201 || demuxer->stream->type == STREAMTYPE_VCD)
202 && demuxer->movi_start != demuxer-> movi_end
205 //We seek to the beginning of the stream, to somewhere in the
206 //middle, and to the end of the stream, while remembering the pts
207 //at each of the three positions. With these pts, we check whether
208 //or not the pts are "linear enough" to justify seeking by the pts
209 //of the stream
211 //The position where the stream is now
212 off_t pos = stream_tell(s);
213 float first_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_start);
214 if(first_pts != -1.0)
216 float middle_pts = read_first_mpeg_pts_at_position(demuxer, (demuxer->movi_end + demuxer->movi_start)/2);
217 if(middle_pts != -1.0)
219 float final_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_end - TIMESTAMP_PROBE_LEN);
220 if(final_pts != -1.0)
222 // found proper first, middle, and final pts.
223 float proportion = (middle_pts-first_pts==0) ? -1 : (final_pts-middle_pts)/(middle_pts-first_pts);
224 // if they are linear enough set has_valid_timestamps
225 if((0.5 < proportion) && (proportion < 2))
227 mpg_d->first_pts = first_pts;
228 mpg_d->first_to_final_pts_len = final_pts - first_pts;
229 mpg_d->has_valid_timestamps = 1;
235 //Cleaning up from seeking in stream
236 demuxer->stream->eof=0;
237 demuxer->video->eof=0;
238 demuxer->audio->eof=0;
240 stream_seek(s,pos);
241 ds_fill_buffer(demuxer->video);
242 } // if ( demuxer->seekable )
243 } // if ( mpg_d )
244 return demuxer;
247 static void demux_close_mpg(demuxer_t* demuxer) {
248 mpg_demuxer_t* mpg_d = demuxer->priv;
249 if (mpg_d) free(mpg_d);
253 static unsigned long long read_mpeg_timestamp(stream_t *s,int c){
254 unsigned int d,e;
255 unsigned long long pts;
256 d=stream_read_word(s);
257 e=stream_read_word(s);
258 if( ((c&1)!=1) || ((d&1)!=1) || ((e&1)!=1) ){
259 ++mpeg_pts_error;
260 return 0; // invalid pts
262 pts=(((uint64_t)((c>>1)&7))<<30)|((d>>1)<<15)|(e>>1);
263 mp_dbg(MSGT_DEMUX,MSGL_DBG3," pts {%"PRIu64"}",pts);
264 return pts;
267 static void new_audio_stream(demuxer_t *demux, int aid){
268 if(!demux->a_streams[aid]){
269 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demux->priv;
270 sh_audio_t* sh_a;
271 new_sh_audio(demux,aid);
272 sh_a = (sh_audio_t*)demux->a_streams[aid];
273 switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id)
274 case 0x00: sh_a->format=0x50;break; // mpeg
275 case 0xA0: sh_a->format=0x10001;break; // dvd pcm
276 case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts
277 else sh_a->format=0x2000;break; // ac3
279 //evo files
280 if((aid & 0xC0) == 0xC0) sh_a->format=0x2000;
281 else if(aid >= 0x98 && aid <= 0x9f) sh_a->format=0x2001;
282 if (mpg_d) mpg_d->a_stream_ids[mpg_d->num_a_streams++] = aid;
284 if(demux->audio->id==-1) demux->audio->id=aid;
287 static int demux_mpg_read_packet(demuxer_t *demux,int id){
288 int d;
289 int len;
290 int set_pts=0; // !=0 iff pts has been set to a proper value
291 unsigned char c=0;
292 unsigned long long pts=0;
293 unsigned long long dts=0;
294 int l;
295 int pes_ext2_subid=-1;
296 double stream_pts = MP_NOPTS_VALUE;
297 demux_stream_t *ds=NULL;
298 demux_packet_t* dp;
299 mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
301 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_read_packet: %X\n",id);
303 // if(id==0x1F0){
304 // demux->synced=0; // force resync after 0x1F0
305 // return -1;
308 // if(id==0x1BA) packet_start_pos=stream_tell(demux->stream);
309 if((id<0x1BC || id>=0x1F0) && id != 0x1FD) return -1;
310 if(id==0x1BE) return -1; // padding stream
311 if(id==0x1BF) return -1; // private2
313 len=stream_read_word(demux->stream);
314 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"PACKET len=%d",len);
315 // if(len==62480){ demux->synced=0;return -1;} /* :) */
316 if(len==0 || len>MAX_PS_PACKETSIZE){
317 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS packet len: %d\n",len);
318 return -2; // invalid packet !!!!!!
321 mpeg_pts_error=0;
323 if(id==0x1BC) {
324 parse_psm(demux, len);
325 return 0;
328 while(len>0){ // Skip stuFFing bytes
329 c=stream_read_char(demux->stream);
330 --len;
331 if(c!=0xFF)break;
333 if((c>>6)==1){ // Read (skip) STD scale & size value
334 // printf(" STD_scale=%d",(c>>5)&1);
335 d=((c&0x1F)<<8)|stream_read_char(demux->stream);
336 len-=2;
337 // printf(" STD_size=%d",d);
338 c=stream_read_char(demux->stream);
340 // Read System-1 stream timestamps:
341 if((c>>4)==2){
342 pts=read_mpeg_timestamp(demux->stream,c);
343 set_pts=1;
344 len-=4;
345 } else
346 if((c>>4)==3){
347 pts=read_mpeg_timestamp(demux->stream,c);
348 c=stream_read_char(demux->stream);
349 if((c>>4)!=1) pts=0; //printf("{ERROR4}");
350 else set_pts = 1;
351 dts=read_mpeg_timestamp(demux->stream,c);
352 len-=4+1+4;
353 } else
354 if((c>>6)==2){
355 int pts_flags;
356 int hdrlen;
357 int parse_ext2;
358 // System-2 (.VOB) stream:
359 c=stream_read_char(demux->stream);
360 pts_flags=c>>6;
361 parse_ext2 = (id == 0x1FD) && ((c & 0x3F) == 1);
362 c=stream_read_char(demux->stream);
363 hdrlen=c;
364 len-=2;
365 mp_dbg(MSGT_DEMUX,MSGL_DBG3," hdrlen=%d (len=%d)",hdrlen,len);
366 if(hdrlen>len){ mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: invalid header length \n"); return -1;}
367 if(pts_flags==2 && hdrlen>=5){
368 c=stream_read_char(demux->stream);
369 pts=read_mpeg_timestamp(demux->stream,c);
370 set_pts=1;
371 len-=5;hdrlen-=5;
372 } else
373 if(pts_flags==3 && hdrlen>=10){
374 c=stream_read_char(demux->stream);
375 pts=read_mpeg_timestamp(demux->stream,c);
376 set_pts=1;
377 c=stream_read_char(demux->stream);
378 dts=read_mpeg_timestamp(demux->stream,c);
379 len-=10;hdrlen-=10;
381 len-=hdrlen;
382 if(parse_ext2 && hdrlen>=3) {
383 c=stream_read_char(demux->stream);
384 hdrlen--;
386 if((c & 0x0F) != 0x0F) {
387 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: pes_extension_flag2 not set, discarding pes packet\n");
388 return -1;
390 if(c & 0x80) { //pes_private_data_flag
391 if(hdrlen<16) {
392 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pes_private_data bytes: %d < 16, discarding pes packet\n", hdrlen);
393 return -1;
395 stream_skip(demux->stream, 16);
396 hdrlen-=16;
398 if(c & 0x40) { //pack_header_field_flag
399 int l = stream_read_char(demux->stream);
400 if(l < 0) //couldn't read from the stream?
401 return -1;
402 hdrlen--;
403 if(l < 0 || hdrlen < l) {
404 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pack_header bytes: hdrlen: %d < skip: %d, discarding pes packet\n",
405 hdrlen, l);
406 return -1;
408 stream_skip(demux->stream, l);
409 hdrlen-=l;
411 if(c & 0x20) { //program_packet_sequence_counter_flag
412 if(hdrlen < 2) {
413 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough program_packet bytes: hdrlen: %d, discarding pes packet\n", hdrlen);
414 return -1;
416 stream_skip(demux->stream, 2);
417 hdrlen-=2;
419 if(c & 0x10) {
420 //STD
421 stream_skip(demux->stream, 2);
422 hdrlen-=2;
424 c=stream_read_char(demux->stream); //pes_extension2 flag
425 hdrlen--;
426 if(c!=0x81) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown pes_extension2 format, len is > 1 \n"); return -1;}
427 c=stream_read_char(demux->stream); //pes_extension2 payload === substream id
428 hdrlen--;
429 if(c<0x55 || c>0x5F) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown vc1 substream_id: 0x%x \n", c); return -1;}
430 pes_ext2_subid=c;
432 if(hdrlen>0)
433 stream_skip(demux->stream,hdrlen); // skip header and stuffing bytes
435 if(id==0x1FD && pes_ext2_subid!=-1) {
436 //==== EVO VC1 STREAMS ===//
437 if(!demux->v_streams[pes_ext2_subid]) new_sh_video(demux,pes_ext2_subid);
438 if(demux->video->id==-1) demux->video->id=pes_ext2_subid;
439 if(demux->video->id==pes_ext2_subid){
440 ds=demux->video;
441 if(!ds->sh) ds->sh=demux->v_streams[pes_ext2_subid];
442 if(priv && ds->sh) {
443 sh_video_t *sh = (sh_video_t *)ds->sh;
444 sh->format = mmioFOURCC('W', 'V', 'C', '1');
448 //============== DVD Audio sub-stream ======================
449 if(id==0x1BD){
450 int aid, rawa52 = 0;
451 off_t tmppos;
452 unsigned int tmp;
454 tmppos = stream_tell(demux->stream);
455 tmp = stream_read_word(demux->stream);
456 stream_seek(demux->stream, tmppos);
457 /// vdr stores A52 without the 4 header bytes, so we have to check this condition first
458 if(tmp == 0x0B77) {
459 aid = 128;
460 rawa52 = 1;
462 else {
463 aid=stream_read_char(demux->stream);--len;
464 if(len<3) return -1; // invalid audio packet
467 // AID:
468 // 0x20..0x3F subtitle
469 // 0x80..0x87 and 0xC0..0xCF AC3 audio
470 // 0x88..0x8F and 0x98..0x9F DTS audio
471 // 0xA0..0xBF PCM audio
473 if((aid & 0xE0) == 0x20){
474 // subtitle:
475 aid&=0x1F;
477 if(!demux->s_streams[aid]){
478 sh_sub_t *sh = new_sh_sub(demux, aid);
479 if (sh) sh->type = 'v';
480 mp_msg(MSGT_DEMUX,MSGL_V,"==> Found subtitle: %d\n",aid);
483 if(demux->sub->id > -1)
484 demux->sub->id &= 0x1F;
485 if(!dvdsub_lang && demux->sub->id == -1)
486 demux->sub->id = aid;
487 if(demux->sub->id==aid){
488 ds=demux->sub;
490 } else if((aid >= 0x80 && aid <= 0x8F) || (aid >= 0x98 && aid <= 0xAF) || (aid >= 0xC0 && aid <= 0xCF)) {
492 // aid=128+(aid&0x7F);
493 // aid=0x80..0xBF
494 new_audio_stream(demux, aid);
495 if(demux->audio->id==aid){
496 int type;
497 ds=demux->audio;
498 if(!ds->sh) ds->sh=demux->a_streams[aid];
499 // READ Packet: Skip additional audio header data:
500 if(!rawa52) {
501 c=stream_read_char(demux->stream);//num of frames
502 type=stream_read_char(demux->stream);//startpos hi
503 type=(type<<8)|stream_read_char(demux->stream);//startpos lo
504 // printf("\r[%02X][%04X]",c,type);
505 len-=3;
507 if((aid&0xE0)==0xA0 && len>=3){
508 unsigned char* hdr;
509 // save audio header as codecdata!
510 if(!((sh_audio_t*)(ds->sh))->codecdata_len){
511 ((sh_audio_t*)(ds->sh))->codecdata=malloc(3);
512 ((sh_audio_t*)(ds->sh))->codecdata_len=3;
514 hdr=((sh_audio_t*)(ds->sh))->codecdata;
515 // read LPCM header:
516 // emphasis[1], mute[1], rvd[1], frame number[5]:
517 hdr[0]=stream_read_char(demux->stream);
518 // printf(" [%01X:%02d]",c>>5,c&31);
519 // quantization[2],freq[2],rvd[1],channels[3]
520 hdr[1]=stream_read_char(demux->stream);
521 // printf("[%01X:%01X] ",c>>4,c&15);
522 // dynamic range control (0x80=off):
523 hdr[2]=stream_read_char(demux->stream);
524 // printf("[%02X] ",c);
525 len-=3;
526 if(len<=0) mp_msg(MSGT_DEMUX,MSGL_V,"End of packet while searching for PCM header\n");
528 // printf(" \n");
529 } // if(demux->audio->id==aid)
531 } else mp_msg(MSGT_DEMUX,MSGL_V,"Unknown 0x1BD substream: 0x%02X \n",aid);
532 } //if(id==0x1BD)
533 } else {
534 if(c!=0x0f){
535 mp_msg(MSGT_DEMUX,MSGL_V," {ERROR5,c=%d} \n",c);
536 return -1; // invalid packet !!!!!!
539 if(mpeg_pts_error) mp_msg(MSGT_DEMUX,MSGL_V," {PTS_err:%d} \n",mpeg_pts_error);
540 mp_dbg(MSGT_DEMUX,MSGL_DBG3," => len=%d\n",len);
542 // if(len<=0 || len>MAX_PS_PACKETSIZE) return -1; // Invalid packet size
543 if(len<=0 || len>MAX_PS_PACKETSIZE){
544 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS data len: %d\n",len);
545 return -1; // invalid packet !!!!!!
548 if(id>=0x1C0 && id<=0x1DF){
549 // mpeg audio
550 int aid=id-0x1C0;
551 new_audio_stream(demux, aid);
552 if(demux->audio->id==aid){
553 ds=demux->audio;
554 if(!ds->sh) ds->sh=demux->a_streams[aid];
555 if(priv && ds->sh) {
556 sh_audio_t *sh = (sh_audio_t *)ds->sh;
557 if(priv->es_map[id - 0x1B0])
558 sh->format = priv->es_map[id - 0x1B0];
559 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
562 } else
563 if(id>=0x1E0 && id<=0x1EF){
564 // mpeg video
565 int aid=id-0x1E0;
566 if(!demux->v_streams[aid]) new_sh_video(demux,aid);
567 if(demux->video->id==-1) demux->video->id=aid;
568 if(demux->video->id==aid){
569 ds=demux->video;
570 if(!ds->sh) ds->sh=demux->v_streams[aid];
571 if(priv && ds->sh) {
572 sh_video_t *sh = (sh_video_t *)ds->sh;
573 if(priv->es_map[id - 0x1B0]) {
574 sh->format = priv->es_map[id - 0x1B0];
575 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
581 if(ds){
582 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Read %d data bytes from packet %04X\n",len,id);
583 // printf("packet start = 0x%X \n",stream_tell(demux->stream)-packet_start_pos);
585 dp=new_demux_packet(len);
586 if(!dp) {
587 mp_dbg(MSGT_DEMUX,MSGL_ERR,"DEMUX_MPG ERROR: couldn't create demux_packet(%d bytes)\n",len);
588 stream_skip(demux->stream,len);
589 return 0;
591 l = stream_read(demux->stream,dp->buffer,len);
592 if(l<len)
593 resize_demux_packet(dp, l);
594 len = l;
595 if(set_pts)
596 dp->pts=pts/90000.0f;
597 dp->pos=demux->filepos;
599 workaround:
600 set dp->stream_pts only when feeding the video stream, or strangely interleaved files
601 (such as SWIII) will show strange alternations in the stream time, wildly going
602 back and forth
604 if(ds == demux->video && stream_control(demux->stream, STREAM_CTRL_GET_CURRENT_TIME,(void *)&stream_pts)!=STREAM_UNSUPPORTED)
605 dp->stream_pts = stream_pts;
606 ds_add_packet(ds,dp);
607 if (demux->priv && set_pts) ((mpg_demuxer_t*)demux->priv)->last_pts = pts/90000.0f;
608 // if(ds==demux->sub) parse_dvdsub(ds->last->buffer,ds->last->len);
609 return 1;
611 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Skipping %d data bytes from packet %04X\n",len,id);
612 if(len<=2356) stream_skip(demux->stream,len);
613 return 0;
616 static int num_elementary_packets100=0;
617 static int num_elementary_packets101=0;
618 static int num_elementary_packets12x=0;
619 static int num_elementary_packets1B6=0;
620 static int num_elementary_packetsPES=0;
621 static int num_mpeg12_startcode=0;
622 static int num_h264_slice=0; //combined slice
623 static int num_h264_dpa=0; //DPA Slice
624 static int num_h264_dpb=0; //DPB Slice
625 static int num_h264_dpc=0; //DPC Slice
626 static int num_h264_idr=0; //IDR Slice
627 static int num_h264_sps=0;
628 static int num_h264_pps=0;
630 static int num_mp3audio_packets=0;
632 static void clear_stats(void)
634 num_elementary_packets100=0;
635 num_elementary_packets101=0;
636 num_elementary_packets1B6=0;
637 num_elementary_packets12x=0;
638 num_elementary_packetsPES=0;
639 num_mpeg12_startcode=0;
640 num_h264_slice=0; //combined slice
641 num_h264_dpa=0; //DPA Slice
642 num_h264_dpb=0; //DPB Slice
643 num_h264_dpc=0; //DPC Slice
644 num_h264_idr=0; //IDR Slice
645 num_h264_sps=0;
646 num_h264_pps=0;
647 num_mp3audio_packets=0;
650 //assumes demuxer->synced < 2
651 static inline void update_stats(int head)
653 if(head==0x1B6) ++num_elementary_packets1B6;
654 else if(head==0x1B3 || head==0x1B8) ++num_mpeg12_startcode;
655 else if(head==0x100) ++num_elementary_packets100;
656 else if(head==0x101) ++num_elementary_packets101;
657 else if(head==0x1BD || (0x1C0<=head && head<=0x1EF))
658 num_elementary_packetsPES++;
659 else if(head>=0x120 && head<=0x12F) ++num_elementary_packets12x;
660 if(head>=0x100 && head<0x1B0)
662 if((head&~0x60) == 0x101) ++num_h264_slice;
663 else if((head&~0x60) == 0x102) ++num_h264_dpa;
664 else if((head&~0x60) == 0x103) ++num_h264_dpb;
665 else if((head&~0x60) == 0x104) ++num_h264_dpc;
666 else if((head&~0x60) == 0x105 && head != 0x105) ++num_h264_idr;
667 else if((head&~0x60) == 0x107 && head != 0x107) ++num_h264_sps;
668 else if((head&~0x60) == 0x108 && head != 0x108) ++num_h264_pps;
672 static int demux_mpg_probe(demuxer_t *demuxer) {
673 int pes=1;
674 int tmp;
675 off_t tmppos;
676 int file_format = DEMUXER_TYPE_UNKNOWN;
678 tmppos=stream_tell(demuxer->stream);
679 tmp=stream_read_dword(demuxer->stream);
680 if(tmp==0x1E0 || tmp==0x1C0) {
681 tmp=stream_read_word(demuxer->stream);
682 if(tmp>1 && tmp<=2048) pes=0; // demuxer->synced=3; // PES...
684 stream_seek(demuxer->stream,tmppos);
686 clear_stats();
688 if(demux_mpg_open(demuxer))
689 file_format=DEMUXER_TYPE_MPEG_PS;
690 else {
691 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",
692 num_elementary_packets100,num_elementary_packets101,
693 num_elementary_packets1B6,num_elementary_packets12x,
694 num_h264_slice, num_h264_dpa,
695 num_h264_dpb, num_h264_dpc=0,
696 num_h264_idr, num_h264_sps=0,
697 num_h264_pps,
698 num_elementary_packetsPES,num_mp3audio_packets, demuxer->synced);
700 //MPEG packet stats: p100: 458 p101: 458 PES: 0 MP3: 1103 (.m2v)
701 if(num_mp3audio_packets>50 && num_mp3audio_packets>2*num_elementary_packets100
702 && abs(num_elementary_packets100-num_elementary_packets101)>2)
703 return file_format;
705 // some hack to get meaningfull error messages to our unhappy users:
706 if(num_mpeg12_startcode>=2 && num_elementary_packets100>=2 && num_elementary_packets101>=2 &&
707 abs(num_elementary_packets101+8-num_elementary_packets100)<16) {
708 if(num_elementary_packetsPES>=4 && num_elementary_packetsPES>=num_elementary_packets100-4) {
709 return file_format;
711 file_format=DEMUXER_TYPE_MPEG_ES; // <-- hack is here :)
712 } else
713 // fuzzy mpeg4-es detection. do NOT enable without heavy testing of mpeg formats detection!
714 if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
715 num_elementary_packetsPES==0 && num_elementary_packets100<=num_elementary_packets12x &&
716 demuxer->synced<2) {
717 file_format=DEMUXER_TYPE_MPEG4_ES;
718 } else
719 // fuzzy h264-es detection. do NOT enable without heavy testing of mpeg formats detection!
720 if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
721 /* FIXME num_h264_sps>=1 && */ num_h264_pps>=1 && num_h264_idr>=1 &&
722 num_elementary_packets1B6==0 && num_elementary_packetsPES==0 &&
723 demuxer->synced<2) {
724 file_format=DEMUXER_TYPE_H264_ES;
725 } else
727 if(demuxer->synced==2)
728 mp_msg(MSGT_DEMUXER,MSGL_ERR,"MPEG: " MSGTR_MissingVideoStreamBug);
729 else
730 mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_NotSystemStream);
733 //FIXME this shouldn't be necessary
734 stream_seek(demuxer->stream,tmppos);
735 return file_format;
738 static int demux_mpg_es_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
739 // Elementary video stream
740 if(demux->stream->eof) return 0;
741 demux->filepos=stream_tell(demux->stream);
742 ds_read_packet(demux->video,demux->stream,STREAM_BUFFER_SIZE,0,demux->filepos,0);
743 return 1;
747 * \brief discard until 0x100 header and return a filled buffer
748 * \param b buffer-end pointer
749 * \param pos current pos in stream, negative since b points to end of buffer
750 * \param s stream to read from
751 * \return new position, differs from original pos when eof hit and thus
752 * b was modified to point to the new end of buffer
754 static int find_end(unsigned char **b, int pos, stream_t *s) {
755 register int state = 0xffffffff;
756 unsigned char *buf = *b;
757 int start = pos;
758 int read, unused;
759 // search already read part
760 while (state != 0x100 && pos) {
761 state = state << 8 | buf[pos++];
763 // continue search in stream
764 while (state != 0x100) {
765 register int c = stream_read_char(s);
766 if (c < 0) break;
767 state = state << 8 | c;
769 // modify previous header (from 0x1bc or 0x1bf to 0x100)
770 buf[start++] = 0;
771 // copy remaining buffer part to current pos
772 memmove(&buf[start], &buf[pos], -pos);
773 unused = start + -pos; // -unused bytes in buffer
774 read = stream_read(s, &buf[unused], -unused);
775 unused += read;
776 // fix buffer so it ends at pos == 0 (eof case)
777 *b = &buf[unused];
778 start -= unused;
779 return start;
783 * This format usually uses an insane bitrate, which makes this function
784 * performance-critical!
785 * Be sure to benchmark any changes with different compiler versions.
787 static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
788 demux_packet_t *pack;
789 int len;
790 demux->filepos = stream_tell(demux->stream);
791 pack = new_demux_packet(STREAM_BUFFER_SIZE);
792 len = stream_read(demux->stream, pack->buffer, STREAM_BUFFER_SIZE);
793 if (len <= 0)
795 free_demux_packet(pack);
796 return 0;
799 register uint32_t state = (uint32_t)demux->priv;
800 register int pos = -len;
801 unsigned char *buf = &pack->buffer[len];
802 do {
803 state = state << 8 | buf[pos];
804 if (unlikely((state | 3) == 0x1bf))
805 pos = find_end(&buf, pos, demux->stream);
806 } while (++pos < 0);
807 demux->priv = (void *)state;
808 len = buf - pack->buffer;
810 if (len < STREAM_BUFFER_SIZE)
811 resize_demux_packet(pack, len);
812 ds_add_packet(ds, pack);
813 return 1;
816 int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
817 unsigned int head=0;
818 int skipped=0;
819 int max_packs=256; // 512kbyte
820 int ret=0;
822 // System stream
824 demux->filepos=stream_tell(demux->stream);
825 #if 1
826 //lame workaround: this is needed to show the progress bar when playing dvdnav://
827 //(ths poor guy doesn't know teh length of the stream at startup)
828 demux->movi_end = demux->stream->end_pos;
829 #endif
830 head=stream_read_dword(demux->stream);
831 if((head&0xFFFFFF00)!=0x100){
832 // sync...
833 demux->filepos-=skipped;
834 while(1){
835 int c=stream_read_char(demux->stream);
836 if(c<0) break; //EOF
837 head<<=8;
838 if(head!=0x100){
839 head|=c;
840 if(mp_check_mp3_header(head)) ++num_mp3audio_packets;
841 ++skipped; //++demux->filepos;
842 continue;
844 head|=c;
845 break;
847 demux->filepos+=skipped;
849 if(stream_eof(demux->stream)) break;
850 // sure: head=0x000001XX
851 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"*** head=0x%X\n",head);
852 if(demux->synced==0){
853 if(head==0x1BA) demux->synced=1; //else
854 // if(head==0x1BD || (head>=0x1C0 && head<=0x1EF)) demux->synced=3; // PES?
855 } else
856 if(demux->synced==1){
857 if(head==0x1BB || head==0x1BD || (head>=0x1C0 && head<=0x1EF)){
858 demux->synced=2;
859 mp_msg(MSGT_DEMUX,MSGL_V,"system stream synced at 0x%"PRIX64" (%"PRId64")!\n",(int64_t)demux->filepos,(int64_t)demux->filepos);
860 num_elementary_packets100=0; // requires for re-sync!
861 num_elementary_packets101=0; // requires for re-sync!
862 } else demux->synced=0;
863 } // else
864 if(demux->synced>=2){
865 ret=demux_mpg_read_packet(demux,head);
866 if(!ret)
867 if(--max_packs==0){
868 demux->stream->eof=1;
869 mp_msg(MSGT_DEMUX,MSGL_ERR,MSGTR_DoesntContainSelectedStream);
870 return 0;
872 if(demux->synced==3) demux->synced=(ret==1)?2:0; // PES detect
873 } else {
874 update_stats(head);
875 if(head>=0x100 && head<0x1B0)
876 mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... elementary video packet found: %03X\n",head);
877 else if((head>=0x1C0 && head<0x1F0) || head==0x1BD)
878 mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... PES packet found: %03X\n",head);
880 if(((num_elementary_packets100>50 && num_elementary_packets101>50) ||
881 (num_elementary_packetsPES>50)) && skipped>4000000){
882 mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be ES/PES stream...\n");
883 demux->stream->eof=1;
884 break;
886 if(num_mp3audio_packets>100 && num_elementary_packets100<10){
887 mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be MP3 stream...\n");
888 demux->stream->eof=1;
889 break;
892 } while(ret!=1);
893 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux: %d bad bytes skipped\n",skipped);
894 if(demux->stream->eof){
895 mp_msg(MSGT_DEMUX,MSGL_V,"MPEG Stream reached EOF\n");
896 return 0;
898 return 1;
901 void skip_audio_frame(sh_audio_t *sh_audio);
903 void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,float audio_delay, int flags){
904 demux_stream_t *d_audio=demuxer->audio;
905 demux_stream_t *d_video=demuxer->video;
906 sh_audio_t *sh_audio=d_audio->sh;
907 sh_video_t *sh_video=d_video->sh;
908 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
909 int precision = 1;
910 float oldpts = 0;
911 off_t oldpos = demuxer->filepos;
912 float newpts = 0;
913 off_t newpos = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : oldpos;
915 if(mpg_d)
916 oldpts = mpg_d->last_pts;
917 newpts = (flags & SEEK_ABSOLUTE) ? 0.0 : oldpts;
918 //================= seek in MPEG ==========================
919 //calculate the pts to seek to
920 if(flags & SEEK_FACTOR) {
921 if (mpg_d && mpg_d->first_to_final_pts_len > 0.0)
922 newpts += mpg_d->first_to_final_pts_len * rel_seek_secs;
923 else
924 newpts += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * oldpts / oldpos;
925 } else
926 newpts += rel_seek_secs;
927 if (newpts < 0) newpts = 0;
929 if(flags&SEEK_FACTOR){
930 // float seek 0..1
931 newpos+=(demuxer->movi_end-demuxer->movi_start)*rel_seek_secs;
932 } else {
933 // time seek (secs)
934 if (mpg_d && mpg_d->has_valid_timestamps) {
935 if (mpg_d->first_to_final_pts_len > 0.0)
936 newpos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / mpg_d->first_to_final_pts_len;
937 else if (oldpts > 0.0)
938 newpos += rel_seek_secs * (oldpos - demuxer->movi_start) / oldpts;
939 } else if(!sh_video || !sh_video->i_bps) // unspecified or VBR
940 newpos+=2324*75*rel_seek_secs; // 174.3 kbyte/sec
941 else
942 newpos+=sh_video->i_bps*rel_seek_secs;
945 while (1) {
946 if(newpos<demuxer->movi_start){
947 if(demuxer->stream->type!=STREAMTYPE_VCD) demuxer->movi_start=0; // for VCD
948 if(newpos<demuxer->movi_start) newpos=demuxer->movi_start;
951 stream_seek(demuxer->stream,newpos);
953 // re-sync video:
954 videobuf_code_len=0; // reset ES stream buffer
956 ds_fill_buffer(d_video);
957 if(sh_audio){
958 ds_fill_buffer(d_audio);
961 while(1){
962 int i;
963 if(sh_audio && !d_audio->eof && d_video->pts && d_audio->pts){
964 float a_pts=d_audio->pts;
965 a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
966 if(d_video->pts>a_pts){
967 skip_audio_frame(sh_audio); // sync audio
968 continue;
971 if(!sh_video) break;
972 i=sync_video_packet(d_video);
973 if(sh_video->format == mmioFOURCC('W', 'V', 'C', '1')) {
974 if(i==0x10E || i==0x10F) //entry point or sequence header
975 break;
976 } else
977 if(sh_video->format == 0x10000004) { //mpeg4
978 if(i==0x1B6) { //vop (frame) startcode
979 int pos = videobuf_len;
980 if(!read_video_packet(d_video)) break; // EOF
981 if((videobuffer[pos+4] & 0x3F) == 0) break; //I-frame
983 } else if(sh_video->format == 0x10000005){ //h264
984 if((i & ~0x60) == 0x105) break;
985 } else { //default mpeg1/2
986 if(i==0x1B3 || i==0x1B8) break; // found it!
988 if(!i || !skip_video_packet(d_video)) break; // EOF?
990 if(!mpg_d)
991 break;
992 if (!precision || abs(newpts - mpg_d->last_pts) < 0.5 || (mpg_d->last_pts == oldpts)) break;
993 if ((newpos - oldpos) * (mpg_d->last_pts - oldpts) < 0) { // invalid timestamps
994 mpg_d->has_valid_timestamps = 0;
995 break;
997 precision--;
998 //prepare another seek because we are off by more than 0.5s
999 if(mpg_d) {
1000 newpos += (newpts - mpg_d->last_pts) * (newpos - oldpos) / (mpg_d->last_pts - oldpts);
1001 demux_flush(demuxer);
1002 demuxer->stream->eof=0; // clear eof flag
1003 d_video->eof=0;
1004 d_audio->eof=0;
1009 int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){
1010 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
1012 switch(cmd) {
1013 case DEMUXER_CTRL_GET_TIME_LENGTH:
1014 if(stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, arg) != STREAM_UNSUPPORTED) {
1015 mp_msg(MSGT_DEMUXER,MSGL_DBG2,"\r\nDEMUX_MPG_CTRL, (%.3lf)\r\n", *((double*)arg));
1016 return DEMUXER_CTRL_GUESS;
1018 if (mpg_d && mpg_d->has_valid_timestamps) {
1019 *((double *)arg)=(double)mpg_d->first_to_final_pts_len;
1020 return DEMUXER_CTRL_OK;
1022 return DEMUXER_CTRL_DONTKNOW;
1024 case DEMUXER_CTRL_GET_PERCENT_POS:
1025 if (mpg_d && mpg_d->has_valid_timestamps && mpg_d->first_to_final_pts_len > 0.0) {
1026 *((int *)arg)=(int)(100 * (mpg_d->last_pts-mpg_d->first_pts) / mpg_d->first_to_final_pts_len);
1027 return DEMUXER_CTRL_OK;
1029 return DEMUXER_CTRL_DONTKNOW;
1031 case DEMUXER_CTRL_SWITCH_AUDIO:
1032 if(! (mpg_d && mpg_d->num_a_streams > 1 && demuxer->audio && demuxer->audio->sh))
1033 return DEMUXER_CTRL_NOTIMPL;
1034 else {
1035 demux_stream_t *d_audio = demuxer->audio;
1036 sh_audio_t *sh_audio = d_audio->sh;
1037 sh_audio_t *sh_a = sh_audio;
1038 int i;
1039 if(!sh_audio)
1040 return DEMUXER_CTRL_NOTIMPL;
1041 if (*((int*)arg) < 0)
1043 for (i = 0; i < mpg_d->num_a_streams; i++) {
1044 if (d_audio->id == mpg_d->a_stream_ids[i]) break;
1046 i = (i+1) % mpg_d->num_a_streams;
1047 sh_a = (sh_audio_t*)demuxer->a_streams[mpg_d->a_stream_ids[i]];
1049 else {
1050 for (i = 0; i < mpg_d->num_a_streams; i++)
1051 if (*((int*)arg) == mpg_d->a_stream_ids[i]) break;
1052 if (i < mpg_d->num_a_streams)
1053 sh_a = (sh_audio_t*)demuxer->a_streams[*((int*)arg)];
1055 if (i < mpg_d->num_a_streams && d_audio->id != mpg_d->a_stream_ids[i]) {
1056 d_audio->id = mpg_d->a_stream_ids[i];
1057 d_audio->sh = sh_a;
1058 ds_free_packs(d_audio);
1061 *((int*)arg) = demuxer->audio->id;
1062 return DEMUXER_CTRL_OK;
1064 default:
1065 return DEMUXER_CTRL_NOTIMPL;
1070 static int demux_mpg_pes_probe(demuxer_t *demuxer) {
1071 demuxer->synced = 3;
1072 return (demux_mpg_probe(demuxer) == DEMUXER_TYPE_MPEG_PS) ? DEMUXER_TYPE_MPEG_PES : 0;
1076 static demuxer_t* demux_mpg_es_open(demuxer_t* demuxer)
1078 sh_video_t *sh_video=NULL;
1080 demuxer->audio->sh = NULL; // ES streams has no audio channel
1081 demuxer->video->sh = new_sh_video(demuxer,0); // create dummy video stream header, id=0
1082 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1084 return demuxer;
1087 static demuxer_t *demux_mpg_gxf_open(demuxer_t *demuxer) {
1088 demuxer->audio->sh = NULL;
1089 demuxer->video->sh = new_sh_video(demuxer,0);
1090 ((sh_video_t *)demuxer->video->sh)->ds = demuxer->video;
1091 demuxer->priv = (void *) 0xffffffff;
1092 return demuxer;
1095 static demuxer_t* demux_mpg_ps_open(demuxer_t* demuxer)
1097 sh_audio_t *sh_audio=NULL;
1098 sh_video_t *sh_video=NULL;
1100 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1102 if(demuxer->audio->id!=-2) {
1103 if(!ds_fill_buffer(demuxer->audio)){
1104 mp_msg(MSGT_DEMUXER,MSGL_INFO,"MPEG: " MSGTR_MissingAudioStream);
1105 demuxer->audio->sh=NULL;
1106 } else {
1107 sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
1111 if(!sh_video->format && ps_probe > 0) {
1112 int head;
1113 off_t pos = stream_tell(demuxer->stream);
1115 clear_stats();
1116 do {
1117 head=sync_video_packet(demuxer->video);
1118 if(!head) break;
1119 update_stats(head);
1120 skip_video_packet(demuxer->video);
1121 } while(stream_tell(demuxer->stream) < pos + ps_probe && !demuxer->stream->eof);
1123 ds_free_packs(demuxer->video);
1124 demuxer->stream->eof=0;
1125 stream_seek(demuxer->stream, pos);
1126 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",
1127 num_elementary_packets100, num_elementary_packets101,
1128 num_elementary_packets1B6, num_elementary_packets12x,
1129 num_h264_slice, num_h264_dpa, num_h264_dpb, num_h264_dpc,
1130 num_h264_idr, num_h264_sps, num_h264_pps);
1132 if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
1133 num_elementary_packets100<=num_elementary_packets12x)
1134 sh_video->format = 0x10000004;
1135 else if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
1136 num_h264_sps>=1 && num_h264_pps>=1 && num_h264_idr>=1 &&
1137 num_elementary_packets1B6==0)
1138 sh_video->format = 0x10000005;
1139 else sh_video->format = 0x10000002;
1142 return demuxer;
1146 const demuxer_desc_t demuxer_desc_mpeg_ps = {
1147 "MPEG PS demuxer",
1148 "mpegps",
1149 "MPEG-PS",
1150 "Arpi?",
1151 "Mpeg",
1152 DEMUXER_TYPE_MPEG_PS,
1153 0, // unsafe autodetect
1154 demux_mpg_probe,
1155 demux_mpg_fill_buffer,
1156 demux_mpg_ps_open,
1157 demux_close_mpg,
1158 demux_seek_mpg,
1159 demux_mpg_control,
1163 const demuxer_desc_t demuxer_desc_mpeg_pes = {
1164 "MPEG PES demuxer",
1165 "mpegpes",
1166 "MPEG-PES",
1167 "Arpi?",
1168 "Mpeg",
1169 DEMUXER_TYPE_MPEG_PES,
1170 0, // unsafe autodetect
1171 demux_mpg_pes_probe,
1172 demux_mpg_fill_buffer,
1173 demux_mpg_ps_open,
1174 demux_close_mpg,
1175 demux_seek_mpg,
1176 demux_mpg_control,
1180 const demuxer_desc_t demuxer_desc_mpeg_gxf = {
1181 "MPEG ES in GXF demuxer",
1182 "mpeggxf",
1183 "MPEG-ES in GXF",
1184 "Reimar Doeffinger",
1185 "Mpeg",
1186 DEMUXER_TYPE_MPEG_GXF,
1187 0, // hack autodetection
1188 NULL,
1189 demux_mpg_gxf_fill_buffer,
1190 demux_mpg_gxf_open,
1191 NULL,
1192 NULL,
1193 NULL
1196 const demuxer_desc_t demuxer_desc_mpeg_es = {
1197 "MPEG ES demuxer",
1198 "mpeges",
1199 "MPEG-ES",
1200 "Arpi?",
1201 "Mpeg",
1202 DEMUXER_TYPE_MPEG_ES,
1203 0, // hack autodetection
1204 NULL,
1205 demux_mpg_es_fill_buffer,
1206 demux_mpg_es_open,
1207 demux_close_mpg,
1208 demux_seek_mpg,
1209 demux_mpg_control,
1213 const demuxer_desc_t demuxer_desc_mpeg4_es = {
1214 "MPEG4 ES demuxer",
1215 "mpeg4es",
1216 "MPEG-ES",
1217 "Arpi?",
1218 "Mpeg",
1219 DEMUXER_TYPE_MPEG4_ES,
1220 0, // hack autodetection
1221 NULL,
1222 demux_mpg_es_fill_buffer,
1223 demux_mpg_es_open,
1224 demux_close_mpg,
1225 demux_seek_mpg,
1226 demux_mpg_control,
1230 const demuxer_desc_t demuxer_desc_h264_es = {
1231 "H.264 ES demuxer",
1232 "h264es",
1233 "H264-ES",
1234 "Arpi?",
1235 "Mpeg",
1236 DEMUXER_TYPE_H264_ES,
1237 0, // hack autodetection
1238 NULL,
1239 demux_mpg_es_fill_buffer,
1240 demux_mpg_es_open,
1241 demux_close_mpg,
1242 demux_seek_mpg,
1243 demux_mpg_control,