Commit files by Steinar Gunderson, forgotten in r30866.
[mplayer/glamo.git] / libmpdemux / demux_mpg.c
blobf6c7fc516926e4e47301c2f3d8e5883bce83268e
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 sh_a->needs_parsing = 1;
274 switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id)
275 case 0x00: sh_a->format=0x50;break; // mpeg
276 case 0xA0: sh_a->format=0x10001;break; // dvd pcm
277 case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts
278 else sh_a->format=0x2000;break; // ac3
280 //evo files
281 if((aid & 0xC0) == 0xC0) sh_a->format=0x2000;
282 else if(aid >= 0x98 && aid <= 0x9f) sh_a->format=0x2001;
283 if (mpg_d) mpg_d->a_stream_ids[mpg_d->num_a_streams++] = aid;
285 if(demux->audio->id==-1) demux->audio->id=aid;
288 static int demux_mpg_read_packet(demuxer_t *demux,int id){
289 int d;
290 int len;
291 int set_pts=0; // !=0 iff pts has been set to a proper value
292 unsigned char c=0;
293 unsigned long long pts=0;
294 unsigned long long dts=0;
295 int l;
296 int pes_ext2_subid=-1;
297 double stream_pts = MP_NOPTS_VALUE;
298 demux_stream_t *ds=NULL;
299 demux_packet_t* dp;
300 mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
302 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_read_packet: %X\n",id);
304 // if(id==0x1F0){
305 // demux->synced=0; // force resync after 0x1F0
306 // return -1;
309 // if(id==0x1BA) packet_start_pos=stream_tell(demux->stream);
310 if((id<0x1BC || id>=0x1F0) && id != 0x1FD) return -1;
311 if(id==0x1BE) return -1; // padding stream
312 if(id==0x1BF) return -1; // private2
314 len=stream_read_word(demux->stream);
315 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"PACKET len=%d",len);
316 // if(len==62480){ demux->synced=0;return -1;} /* :) */
317 if(len==0 || len>MAX_PS_PACKETSIZE){
318 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS packet len: %d\n",len);
319 return -2; // invalid packet !!!!!!
322 mpeg_pts_error=0;
324 if(id==0x1BC) {
325 parse_psm(demux, len);
326 return 0;
329 while(len>0){ // Skip stuFFing bytes
330 c=stream_read_char(demux->stream);
331 --len;
332 if(c!=0xFF)break;
334 if((c>>6)==1){ // Read (skip) STD scale & size value
335 // printf(" STD_scale=%d",(c>>5)&1);
336 d=((c&0x1F)<<8)|stream_read_char(demux->stream);
337 len-=2;
338 // printf(" STD_size=%d",d);
339 c=stream_read_char(demux->stream);
341 // Read System-1 stream timestamps:
342 if((c>>4)==2){
343 pts=read_mpeg_timestamp(demux->stream,c);
344 set_pts=1;
345 len-=4;
346 } else
347 if((c>>4)==3){
348 pts=read_mpeg_timestamp(demux->stream,c);
349 c=stream_read_char(demux->stream);
350 if((c>>4)!=1) pts=0; //printf("{ERROR4}");
351 else set_pts = 1;
352 dts=read_mpeg_timestamp(demux->stream,c);
353 len-=4+1+4;
354 } else
355 if((c>>6)==2){
356 int pts_flags;
357 int hdrlen;
358 int parse_ext2;
359 // System-2 (.VOB) stream:
360 c=stream_read_char(demux->stream);
361 pts_flags=c>>6;
362 parse_ext2 = (id == 0x1FD) && ((c & 0x3F) == 1);
363 c=stream_read_char(demux->stream);
364 hdrlen=c;
365 len-=2;
366 mp_dbg(MSGT_DEMUX,MSGL_DBG3," hdrlen=%d (len=%d)",hdrlen,len);
367 if(hdrlen>len){ mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: invalid header length \n"); return -1;}
368 if(pts_flags==2 && hdrlen>=5){
369 c=stream_read_char(demux->stream);
370 pts=read_mpeg_timestamp(demux->stream,c);
371 set_pts=1;
372 len-=5;hdrlen-=5;
373 } else
374 if(pts_flags==3 && hdrlen>=10){
375 c=stream_read_char(demux->stream);
376 pts=read_mpeg_timestamp(demux->stream,c);
377 set_pts=1;
378 c=stream_read_char(demux->stream);
379 dts=read_mpeg_timestamp(demux->stream,c);
380 len-=10;hdrlen-=10;
382 len-=hdrlen;
383 if(parse_ext2 && hdrlen>=3) {
384 c=stream_read_char(demux->stream);
385 hdrlen--;
387 if((c & 0x0F) != 0x0F) {
388 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: pes_extension_flag2 not set, discarding pes packet\n");
389 return -1;
391 if(c & 0x80) { //pes_private_data_flag
392 if(hdrlen<16) {
393 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pes_private_data bytes: %d < 16, discarding pes packet\n", hdrlen);
394 return -1;
396 stream_skip(demux->stream, 16);
397 hdrlen-=16;
399 if(c & 0x40) { //pack_header_field_flag
400 int l = stream_read_char(demux->stream);
401 if(l < 0) //couldn't read from the stream?
402 return -1;
403 hdrlen--;
404 if(l < 0 || hdrlen < l) {
405 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pack_header bytes: hdrlen: %d < skip: %d, discarding pes packet\n",
406 hdrlen, l);
407 return -1;
409 stream_skip(demux->stream, l);
410 hdrlen-=l;
412 if(c & 0x20) { //program_packet_sequence_counter_flag
413 if(hdrlen < 2) {
414 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough program_packet bytes: hdrlen: %d, discarding pes packet\n", hdrlen);
415 return -1;
417 stream_skip(demux->stream, 2);
418 hdrlen-=2;
420 if(c & 0x10) {
421 //STD
422 stream_skip(demux->stream, 2);
423 hdrlen-=2;
425 c=stream_read_char(demux->stream); //pes_extension2 flag
426 hdrlen--;
427 if(c!=0x81) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown pes_extension2 format, len is > 1 \n"); return -1;}
428 c=stream_read_char(demux->stream); //pes_extension2 payload === substream id
429 hdrlen--;
430 if(c<0x55 || c>0x5F) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown vc1 substream_id: 0x%x \n", c); return -1;}
431 pes_ext2_subid=c;
433 if(hdrlen>0)
434 stream_skip(demux->stream,hdrlen); // skip header and stuffing bytes
436 if(id==0x1FD && pes_ext2_subid!=-1) {
437 //==== EVO VC1 STREAMS ===//
438 if(!demux->v_streams[pes_ext2_subid]) new_sh_video(demux,pes_ext2_subid);
439 if(demux->video->id==-1) demux->video->id=pes_ext2_subid;
440 if(demux->video->id==pes_ext2_subid){
441 ds=demux->video;
442 if(!ds->sh) ds->sh=demux->v_streams[pes_ext2_subid];
443 if(priv && ds->sh) {
444 sh_video_t *sh = (sh_video_t *)ds->sh;
445 sh->format = mmioFOURCC('W', 'V', 'C', '1');
449 //============== DVD Audio sub-stream ======================
450 if(id==0x1BD){
451 int aid, rawa52 = 0;
452 off_t tmppos;
453 unsigned int tmp;
455 tmppos = stream_tell(demux->stream);
456 tmp = stream_read_word(demux->stream);
457 stream_seek(demux->stream, tmppos);
458 /// vdr stores A52 without the 4 header bytes, so we have to check this condition first
459 if(tmp == 0x0B77) {
460 aid = 128;
461 rawa52 = 1;
463 else {
464 aid=stream_read_char(demux->stream);--len;
465 if(len<3) return -1; // invalid audio packet
468 // AID:
469 // 0x20..0x3F subtitle
470 // 0x80..0x87 and 0xC0..0xCF AC3 audio
471 // 0x88..0x8F and 0x98..0x9F DTS audio
472 // 0xA0..0xBF PCM audio
474 if((aid & 0xE0) == 0x20){
475 // subtitle:
476 aid&=0x1F;
478 if(!demux->s_streams[aid]){
479 sh_sub_t *sh = new_sh_sub(demux, aid);
480 if (sh) sh->type = 'v';
481 mp_msg(MSGT_DEMUX,MSGL_V,"==> Found subtitle: %d\n",aid);
484 if(demux->sub->id > -1)
485 demux->sub->id &= 0x1F;
486 if(!dvdsub_lang && demux->sub->id == -1)
487 demux->sub->id = aid;
488 if(demux->sub->id==aid){
489 ds=demux->sub;
491 } else if((aid >= 0x80 && aid <= 0x8F) || (aid >= 0x98 && aid <= 0xAF) || (aid >= 0xC0 && aid <= 0xCF)) {
493 // aid=128+(aid&0x7F);
494 // aid=0x80..0xBF
495 new_audio_stream(demux, aid);
496 if(demux->audio->id==aid){
497 int type;
498 ds=demux->audio;
499 if(!ds->sh) ds->sh=demux->a_streams[aid];
500 // READ Packet: Skip additional audio header data:
501 if(!rawa52) {
502 c=stream_read_char(demux->stream);//num of frames
503 type=stream_read_char(demux->stream);//startpos hi
504 type=(type<<8)|stream_read_char(demux->stream);//startpos lo
505 // printf("\r[%02X][%04X]",c,type);
506 len-=3;
508 if((aid&0xE0)==0xA0 && len>=3){
509 unsigned char* hdr;
510 // save audio header as codecdata!
511 if(!((sh_audio_t*)(ds->sh))->codecdata_len){
512 ((sh_audio_t*)(ds->sh))->codecdata=malloc(3);
513 ((sh_audio_t*)(ds->sh))->codecdata_len=3;
515 hdr=((sh_audio_t*)(ds->sh))->codecdata;
516 // read LPCM header:
517 // emphasis[1], mute[1], rvd[1], frame number[5]:
518 hdr[0]=stream_read_char(demux->stream);
519 // printf(" [%01X:%02d]",c>>5,c&31);
520 // quantization[2],freq[2],rvd[1],channels[3]
521 hdr[1]=stream_read_char(demux->stream);
522 // printf("[%01X:%01X] ",c>>4,c&15);
523 // dynamic range control (0x80=off):
524 hdr[2]=stream_read_char(demux->stream);
525 // printf("[%02X] ",c);
526 len-=3;
527 if(len<=0) mp_msg(MSGT_DEMUX,MSGL_V,"End of packet while searching for PCM header\n");
529 // printf(" \n");
530 } // if(demux->audio->id==aid)
532 } else mp_msg(MSGT_DEMUX,MSGL_V,"Unknown 0x1BD substream: 0x%02X \n",aid);
533 } //if(id==0x1BD)
534 } else {
535 if(c!=0x0f){
536 mp_msg(MSGT_DEMUX,MSGL_V," {ERROR5,c=%d} \n",c);
537 return -1; // invalid packet !!!!!!
540 if(mpeg_pts_error) mp_msg(MSGT_DEMUX,MSGL_V," {PTS_err:%d} \n",mpeg_pts_error);
541 mp_dbg(MSGT_DEMUX,MSGL_DBG3," => len=%d\n",len);
543 // if(len<=0 || len>MAX_PS_PACKETSIZE) return -1; // Invalid packet size
544 if(len<=0 || len>MAX_PS_PACKETSIZE){
545 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS data len: %d\n",len);
546 return -1; // invalid packet !!!!!!
549 if(id>=0x1C0 && id<=0x1DF){
550 // mpeg audio
551 int aid=id-0x1C0;
552 new_audio_stream(demux, aid);
553 if(demux->audio->id==aid){
554 ds=demux->audio;
555 if(!ds->sh) ds->sh=demux->a_streams[aid];
556 if(priv && ds->sh) {
557 sh_audio_t *sh = (sh_audio_t *)ds->sh;
558 if(priv->es_map[id - 0x1B0])
559 sh->format = priv->es_map[id - 0x1B0];
560 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
563 } else
564 if(id>=0x1E0 && id<=0x1EF){
565 // mpeg video
566 int aid=id-0x1E0;
567 if(!demux->v_streams[aid]) new_sh_video(demux,aid);
568 if(demux->video->id==-1) demux->video->id=aid;
569 if(demux->video->id==aid){
570 ds=demux->video;
571 if(!ds->sh) ds->sh=demux->v_streams[aid];
572 if(priv && ds->sh) {
573 sh_video_t *sh = (sh_video_t *)ds->sh;
574 if(priv->es_map[id - 0x1B0]) {
575 sh->format = priv->es_map[id - 0x1B0];
576 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
582 if(ds){
583 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Read %d data bytes from packet %04X\n",len,id);
584 // printf("packet start = 0x%X \n",stream_tell(demux->stream)-packet_start_pos);
586 dp=new_demux_packet(len);
587 if(!dp) {
588 mp_dbg(MSGT_DEMUX,MSGL_ERR,"DEMUX_MPG ERROR: couldn't create demux_packet(%d bytes)\n",len);
589 stream_skip(demux->stream,len);
590 return 0;
592 l = stream_read(demux->stream,dp->buffer,len);
593 if(l<len)
594 resize_demux_packet(dp, l);
595 len = l;
596 if(set_pts)
597 dp->pts=pts/90000.0f;
598 dp->pos=demux->filepos;
600 workaround:
601 set dp->stream_pts only when feeding the video stream, or strangely interleaved files
602 (such as SWIII) will show strange alternations in the stream time, wildly going
603 back and forth
605 if(ds == demux->video && stream_control(demux->stream, STREAM_CTRL_GET_CURRENT_TIME,(void *)&stream_pts)!=STREAM_UNSUPPORTED)
606 dp->stream_pts = stream_pts;
607 ds_add_packet(ds,dp);
608 if (demux->priv && set_pts) ((mpg_demuxer_t*)demux->priv)->last_pts = pts/90000.0f;
609 // if(ds==demux->sub) parse_dvdsub(ds->last->buffer,ds->last->len);
610 return 1;
612 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Skipping %d data bytes from packet %04X\n",len,id);
613 if(len<=2356) stream_skip(demux->stream,len);
614 return 0;
617 static int num_elementary_packets100=0;
618 static int num_elementary_packets101=0;
619 static int num_elementary_packets12x=0;
620 static int num_elementary_packets1B6=0;
621 static int num_elementary_packetsPES=0;
622 static int num_mpeg12_startcode=0;
623 static int num_h264_slice=0; //combined slice
624 static int num_h264_dpa=0; //DPA Slice
625 static int num_h264_dpb=0; //DPB Slice
626 static int num_h264_dpc=0; //DPC Slice
627 static int num_h264_idr=0; //IDR Slice
628 static int num_h264_sps=0;
629 static int num_h264_pps=0;
631 static int num_mp3audio_packets=0;
633 static void clear_stats(void)
635 num_elementary_packets100=0;
636 num_elementary_packets101=0;
637 num_elementary_packets1B6=0;
638 num_elementary_packets12x=0;
639 num_elementary_packetsPES=0;
640 num_mpeg12_startcode=0;
641 num_h264_slice=0; //combined slice
642 num_h264_dpa=0; //DPA Slice
643 num_h264_dpb=0; //DPB Slice
644 num_h264_dpc=0; //DPC Slice
645 num_h264_idr=0; //IDR Slice
646 num_h264_sps=0;
647 num_h264_pps=0;
648 num_mp3audio_packets=0;
651 //assumes demuxer->synced < 2
652 static inline void update_stats(int head)
654 if(head==0x1B6) ++num_elementary_packets1B6;
655 else if(head==0x1B3 || head==0x1B8) ++num_mpeg12_startcode;
656 else if(head==0x100) ++num_elementary_packets100;
657 else if(head==0x101) ++num_elementary_packets101;
658 else if(head==0x1BD || (0x1C0<=head && head<=0x1EF))
659 num_elementary_packetsPES++;
660 else if(head>=0x120 && head<=0x12F) ++num_elementary_packets12x;
661 if(head>=0x100 && head<0x1B0)
663 if((head&~0x60) == 0x101) ++num_h264_slice;
664 else if((head&~0x60) == 0x102) ++num_h264_dpa;
665 else if((head&~0x60) == 0x103) ++num_h264_dpb;
666 else if((head&~0x60) == 0x104) ++num_h264_dpc;
667 else if((head&~0x60) == 0x105 && head != 0x105) ++num_h264_idr;
668 else if((head&~0x60) == 0x107 && head != 0x107) ++num_h264_sps;
669 else if((head&~0x60) == 0x108 && head != 0x108) ++num_h264_pps;
673 static int demux_mpg_probe(demuxer_t *demuxer) {
674 int pes=1;
675 int tmp;
676 off_t tmppos;
677 int file_format = DEMUXER_TYPE_UNKNOWN;
679 tmppos=stream_tell(demuxer->stream);
680 tmp=stream_read_dword(demuxer->stream);
681 if(tmp==0x1E0 || tmp==0x1C0) {
682 tmp=stream_read_word(demuxer->stream);
683 if(tmp>1 && tmp<=2048) pes=0; // demuxer->synced=3; // PES...
685 stream_seek(demuxer->stream,tmppos);
687 clear_stats();
689 if(demux_mpg_open(demuxer))
690 file_format=DEMUXER_TYPE_MPEG_PS;
691 else {
692 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",
693 num_elementary_packets100,num_elementary_packets101,
694 num_elementary_packets1B6,num_elementary_packets12x,
695 num_h264_slice, num_h264_dpa,
696 num_h264_dpb, num_h264_dpc=0,
697 num_h264_idr, num_h264_sps=0,
698 num_h264_pps,
699 num_elementary_packetsPES,num_mp3audio_packets, demuxer->synced);
701 //MPEG packet stats: p100: 458 p101: 458 PES: 0 MP3: 1103 (.m2v)
702 if(num_mp3audio_packets>50 && num_mp3audio_packets>2*num_elementary_packets100
703 && abs(num_elementary_packets100-num_elementary_packets101)>2)
704 return file_format;
706 // some hack to get meaningfull error messages to our unhappy users:
707 if(num_mpeg12_startcode>=2 && num_elementary_packets100>=2 && num_elementary_packets101>=2 &&
708 abs(num_elementary_packets101+8-num_elementary_packets100)<16) {
709 if(num_elementary_packetsPES>=4 && num_elementary_packetsPES>=num_elementary_packets100-4) {
710 return file_format;
712 file_format=DEMUXER_TYPE_MPEG_ES; // <-- hack is here :)
713 } else
714 // fuzzy mpeg4-es detection. do NOT enable without heavy testing of mpeg formats detection!
715 if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
716 num_elementary_packetsPES==0 && num_elementary_packets100<=num_elementary_packets12x &&
717 demuxer->synced<2) {
718 file_format=DEMUXER_TYPE_MPEG4_ES;
719 } else
720 // fuzzy h264-es detection. do NOT enable without heavy testing of mpeg formats detection!
721 if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
722 /* FIXME num_h264_sps>=1 && */ num_h264_pps>=1 && num_h264_idr>=1 &&
723 num_elementary_packets1B6==0 && num_elementary_packetsPES==0 &&
724 demuxer->synced<2) {
725 file_format=DEMUXER_TYPE_H264_ES;
726 } else
728 if(demuxer->synced==2)
729 mp_msg(MSGT_DEMUXER,MSGL_ERR,"MPEG: " MSGTR_MissingVideoStreamBug);
730 else
731 mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_NotSystemStream);
734 //FIXME this shouldn't be necessary
735 stream_seek(demuxer->stream,tmppos);
736 return file_format;
739 static int demux_mpg_es_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
740 // Elementary video stream
741 if(demux->stream->eof) return 0;
742 demux->filepos=stream_tell(demux->stream);
743 ds_read_packet(demux->video,demux->stream,STREAM_BUFFER_SIZE,0,demux->filepos,0);
744 return 1;
748 * \brief discard until 0x100 header and return a filled buffer
749 * \param b buffer-end pointer
750 * \param pos current pos in stream, negative since b points to end of buffer
751 * \param s stream to read from
752 * \return new position, differs from original pos when eof hit and thus
753 * b was modified to point to the new end of buffer
755 static int find_end(unsigned char **b, int pos, stream_t *s) {
756 register int state = 0xffffffff;
757 unsigned char *buf = *b;
758 int start = pos;
759 int read, unused;
760 // search already read part
761 while (state != 0x100 && pos) {
762 state = state << 8 | buf[pos++];
764 // continue search in stream
765 while (state != 0x100) {
766 register int c = stream_read_char(s);
767 if (c < 0) break;
768 state = state << 8 | c;
770 // modify previous header (from 0x1bc or 0x1bf to 0x100)
771 buf[start++] = 0;
772 // copy remaining buffer part to current pos
773 memmove(&buf[start], &buf[pos], -pos);
774 unused = start + -pos; // -unused bytes in buffer
775 read = stream_read(s, &buf[unused], -unused);
776 unused += read;
777 // fix buffer so it ends at pos == 0 (eof case)
778 *b = &buf[unused];
779 start -= unused;
780 return start;
784 * This format usually uses an insane bitrate, which makes this function
785 * performance-critical!
786 * Be sure to benchmark any changes with different compiler versions.
788 static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
789 demux_packet_t *pack;
790 int len;
791 demux->filepos = stream_tell(demux->stream);
792 pack = new_demux_packet(STREAM_BUFFER_SIZE);
793 len = stream_read(demux->stream, pack->buffer, STREAM_BUFFER_SIZE);
794 if (len <= 0)
796 free_demux_packet(pack);
797 return 0;
800 register uint32_t state = (uint32_t)demux->priv;
801 register int pos = -len;
802 unsigned char *buf = &pack->buffer[len];
803 do {
804 state = state << 8 | buf[pos];
805 if (unlikely((state | 3) == 0x1bf))
806 pos = find_end(&buf, pos, demux->stream);
807 } while (++pos < 0);
808 demux->priv = (void *)state;
809 len = buf - pack->buffer;
811 if (len < STREAM_BUFFER_SIZE)
812 resize_demux_packet(pack, len);
813 ds_add_packet(ds, pack);
814 return 1;
817 static int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
819 unsigned int head=0;
820 int skipped=0;
821 int max_packs=256; // 512kbyte
822 int ret=0;
824 // System stream
826 demux->filepos=stream_tell(demux->stream);
827 //lame workaround: this is needed to show the progress bar when playing dvdnav://
828 //(ths poor guy doesn't know teh length of the stream at startup)
829 demux->movi_end = demux->stream->end_pos;
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 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;
911 int precision = 1;
912 float oldpts = 0;
913 off_t oldpos = demuxer->filepos;
914 float newpts = 0;
915 off_t newpos = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : oldpos;
917 if(mpg_d)
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;
925 else
926 newpts += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * oldpts / oldpos;
927 } else
928 newpts += rel_seek_secs;
929 if (newpts < 0) newpts = 0;
931 if(flags&SEEK_FACTOR){
932 // float seek 0..1
933 newpos+=(demuxer->movi_end-demuxer->movi_start)*rel_seek_secs;
934 } else {
935 // time 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
943 else
944 newpos+=sh_video->i_bps*rel_seek_secs;
947 while (1) {
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);
955 // re-sync video:
956 videobuf_code_len=0; // reset ES stream buffer
958 ds_fill_buffer(d_video);
959 if(sh_audio){
960 ds_fill_buffer(d_audio);
963 while(1){
964 int i;
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
970 continue;
973 if(!sh_video) break;
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
977 break;
978 } else
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?
992 if(!mpg_d)
993 break;
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;
997 break;
999 precision--;
1000 //prepare another seek because we are off by more than 0.5s
1001 if(mpg_d) {
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
1005 d_video->eof=0;
1006 d_audio->eof=0;
1011 static int demux_mpg_control(demuxer_t *demuxer, int cmd, void *arg)
1013 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
1015 switch(cmd) {
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, (%.3lf)\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;
1037 else {
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;
1041 int i;
1042 if(!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]];
1052 else {
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];
1060 d_audio->sh = sh_a;
1061 ds_free_packs(d_audio);
1064 *((int*)arg) = demuxer->audio->id;
1065 return DEMUXER_CTRL_OK;
1067 default:
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;
1087 return demuxer;
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;
1095 return demuxer;
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: " MSGTR_MissingAudioStream);
1108 demuxer->audio->sh=NULL;
1109 } else {
1110 sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
1114 if(!sh_video->format && ps_probe > 0) {
1115 int head;
1116 off_t pos = stream_tell(demuxer->stream);
1118 clear_stats();
1119 do {
1120 head=sync_video_packet(demuxer->video);
1121 if(!head) break;
1122 update_stats(head);
1123 skip_video_packet(demuxer->video);
1124 } while(stream_tell(demuxer->stream) < pos + ps_probe && !demuxer->stream->eof);
1126 ds_free_packs(demuxer->video);
1127 demuxer->stream->eof=0;
1128 stream_seek(demuxer->stream, pos);
1129 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",
1130 num_elementary_packets100, num_elementary_packets101,
1131 num_elementary_packets1B6, num_elementary_packets12x,
1132 num_h264_slice, num_h264_dpa, num_h264_dpb, num_h264_dpc,
1133 num_h264_idr, num_h264_sps, num_h264_pps);
1135 if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
1136 num_elementary_packets100<=num_elementary_packets12x)
1137 sh_video->format = 0x10000004;
1138 else if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
1139 num_h264_sps>=1 && num_h264_pps>=1 && num_h264_idr>=1 &&
1140 num_elementary_packets1B6==0)
1141 sh_video->format = 0x10000005;
1142 else sh_video->format = 0x10000002;
1145 return demuxer;
1149 const demuxer_desc_t demuxer_desc_mpeg_ps = {
1150 "MPEG PS demuxer",
1151 "mpegps",
1152 "MPEG-PS",
1153 "Arpi?",
1154 "Mpeg",
1155 DEMUXER_TYPE_MPEG_PS,
1156 0, // unsafe autodetect
1157 demux_mpg_probe,
1158 demux_mpg_fill_buffer,
1159 demux_mpg_ps_open,
1160 demux_close_mpg,
1161 demux_seek_mpg,
1162 demux_mpg_control,
1166 const demuxer_desc_t demuxer_desc_mpeg_pes = {
1167 "MPEG PES demuxer",
1168 "mpegpes",
1169 "MPEG-PES",
1170 "Arpi?",
1171 "Mpeg",
1172 DEMUXER_TYPE_MPEG_PES,
1173 0, // unsafe autodetect
1174 demux_mpg_pes_probe,
1175 demux_mpg_fill_buffer,
1176 demux_mpg_ps_open,
1177 demux_close_mpg,
1178 demux_seek_mpg,
1179 demux_mpg_control,
1183 const demuxer_desc_t demuxer_desc_mpeg_gxf = {
1184 "MPEG ES in GXF demuxer",
1185 "mpeggxf",
1186 "MPEG-ES in GXF",
1187 "Reimar Doeffinger",
1188 "Mpeg",
1189 DEMUXER_TYPE_MPEG_GXF,
1190 0, // hack autodetection
1191 NULL,
1192 demux_mpg_gxf_fill_buffer,
1193 demux_mpg_gxf_open,
1194 NULL,
1195 NULL,
1196 NULL
1199 const demuxer_desc_t demuxer_desc_mpeg_es = {
1200 "MPEG ES demuxer",
1201 "mpeges",
1202 "MPEG-ES",
1203 "Arpi?",
1204 "Mpeg",
1205 DEMUXER_TYPE_MPEG_ES,
1206 0, // hack autodetection
1207 NULL,
1208 demux_mpg_es_fill_buffer,
1209 demux_mpg_es_open,
1210 demux_close_mpg,
1211 demux_seek_mpg,
1212 demux_mpg_control,
1216 const demuxer_desc_t demuxer_desc_mpeg4_es = {
1217 "MPEG4 ES demuxer",
1218 "mpeg4es",
1219 "MPEG-ES",
1220 "Arpi?",
1221 "Mpeg",
1222 DEMUXER_TYPE_MPEG4_ES,
1223 0, // hack autodetection
1224 NULL,
1225 demux_mpg_es_fill_buffer,
1226 demux_mpg_es_open,
1227 demux_close_mpg,
1228 demux_seek_mpg,
1229 demux_mpg_control,
1233 const demuxer_desc_t demuxer_desc_h264_es = {
1234 "H.264 ES demuxer",
1235 "h264es",
1236 "H264-ES",
1237 "Arpi?",
1238 "Mpeg",
1239 DEMUXER_TYPE_H264_ES,
1240 0, // hack autodetection
1241 NULL,
1242 demux_mpg_es_fill_buffer,
1243 demux_mpg_es_open,
1244 demux_close_mpg,
1245 demux_seek_mpg,
1246 demux_mpg_control,