vo_kva: Restore all the attributes after changing aspect ratio
[mplayer/glamo.git] / libmpdemux / demux_mpg.c
blob6c257b5869e063e1dc41664663ae73337c1d74bc
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 "options.h"
31 #include "libmpcodecs/dec_audio.h"
32 #include "stream/stream.h"
33 #include "demuxer.h"
34 #include "parse_es.h"
35 #include "stheader.h"
36 #include "mp3_hdr.h"
38 //#define MAX_PS_PACKETSIZE 2048
39 #define MAX_PS_PACKETSIZE (224*1024)
41 #define UNKNOWN 0
42 #define VIDEO_MPEG1 0x10000001
43 #define VIDEO_MPEG2 0x10000002
44 #define VIDEO_MPEG4 0x10000004
45 #define VIDEO_H264 0x10000005
46 #define AUDIO_MP2 0x50
47 #define AUDIO_A52 0x2000
48 #define AUDIO_LPCM_BE 0x10001
49 #define AUDIO_AAC mmioFOURCC('M', 'P', '4', 'A')
51 typedef struct mpg_demuxer {
52 float last_pts;
53 float first_pts; // first pts found in stream
54 float first_to_final_pts_len; // difference between final pts and first pts
55 int has_valid_timestamps; // !=0 iff time stamps look linear
56 // (not necessarily starting with 0)
57 unsigned int es_map[0x40]; //es map of stream types (associated to the pes id) from 0xb0 to 0xef
58 int num_a_streams;
59 int a_stream_ids[MAX_A_STREAMS];
60 } mpg_demuxer_t;
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(!demux->opts->sub_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: %s",
730 mp_gtext("Missing video stream!? Contact the author, it may be a bug :(\n"));
731 else
732 mp_tmsg(MSGT_DEMUXER,MSGL_V,"Not MPEG System Stream format... (maybe Transport Stream?)\n");
735 //FIXME this shouldn't be necessary
736 stream_seek(demuxer->stream,tmppos);
737 return file_format;
740 static int demux_mpg_es_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
741 // Elementary video stream
742 if(demux->stream->eof) return 0;
743 demux->filepos=stream_tell(demux->stream);
744 ds_read_packet(demux->video,demux->stream,STREAM_BUFFER_SIZE,0,demux->filepos,0);
745 return 1;
749 * \brief discard until 0x100 header and return a filled buffer
750 * \param b buffer-end pointer
751 * \param pos current pos in stream, negative since b points to end of buffer
752 * \param s stream to read from
753 * \return new position, differs from original pos when eof hit and thus
754 * b was modified to point to the new end of buffer
756 static int find_end(unsigned char **b, int pos, stream_t *s) {
757 register int state = 0xffffffff;
758 unsigned char *buf = *b;
759 int start = pos;
760 int read, unused;
761 // search already read part
762 while (state != 0x100 && pos) {
763 state = state << 8 | buf[pos++];
765 // continue search in stream
766 while (state != 0x100) {
767 register int c = stream_read_char(s);
768 if (c < 0) break;
769 state = state << 8 | c;
771 // modify previous header (from 0x1bc or 0x1bf to 0x100)
772 buf[start++] = 0;
773 // copy remaining buffer part to current pos
774 memmove(&buf[start], &buf[pos], -pos);
775 unused = start + -pos; // -unused bytes in buffer
776 read = stream_read(s, &buf[unused], -unused);
777 unused += read;
778 // fix buffer so it ends at pos == 0 (eof case)
779 *b = &buf[unused];
780 start -= unused;
781 return start;
785 * This format usually uses an insane bitrate, which makes this function
786 * performance-critical!
787 * Be sure to benchmark any changes with different compiler versions.
789 static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
790 demux_packet_t *pack;
791 int len;
792 demux->filepos = stream_tell(demux->stream);
793 pack = new_demux_packet(STREAM_BUFFER_SIZE);
794 len = stream_read(demux->stream, pack->buffer, STREAM_BUFFER_SIZE);
795 if (len <= 0)
797 free_demux_packet(pack);
798 return 0;
801 register uint32_t state = (uint32_t)demux->priv;
802 register int pos = -len;
803 unsigned char *buf = &pack->buffer[len];
804 do {
805 state = state << 8 | buf[pos];
806 if (unlikely((state | 3) == 0x1bf))
807 pos = find_end(&buf, pos, demux->stream);
808 } while (++pos < 0);
809 demux->priv = (void *)state;
810 len = buf - pack->buffer;
812 if (len < STREAM_BUFFER_SIZE)
813 resize_demux_packet(pack, len);
814 ds_add_packet(ds, pack);
815 return 1;
818 static int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
820 unsigned int head=0;
821 int skipped=0;
822 int max_packs=256; // 512kbyte
823 int ret=0;
825 // System stream
827 demux->filepos=stream_tell(demux->stream);
828 //lame workaround: this is needed to show the progress bar when playing dvdnav://
829 //(ths poor guy doesn't know teh length of the stream at startup)
830 demux->movi_end = demux->stream->end_pos;
831 head=stream_read_dword(demux->stream);
832 if((head&0xFFFFFF00)!=0x100){
833 // sync...
834 demux->filepos-=skipped;
835 while(1){
836 int c=stream_read_char(demux->stream);
837 if(c<0) break; //EOF
838 head<<=8;
839 if(head!=0x100){
840 head|=c;
841 if(mp_check_mp3_header(head)) ++num_mp3audio_packets;
842 ++skipped; //++demux->filepos;
843 continue;
845 head|=c;
846 break;
848 demux->filepos+=skipped;
850 if(stream_eof(demux->stream)) break;
851 // sure: head=0x000001XX
852 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"*** head=0x%X\n",head);
853 if(demux->synced==0){
854 if(head==0x1BA) demux->synced=1; //else
855 // if(head==0x1BD || (head>=0x1C0 && head<=0x1EF)) demux->synced=3; // PES?
856 } else
857 if(demux->synced==1){
858 if(head==0x1BB || head==0x1BD || (head>=0x1C0 && head<=0x1EF)){
859 demux->synced=2;
860 mp_msg(MSGT_DEMUX,MSGL_V,"system stream synced at 0x%"PRIX64" (%"PRId64")!\n",(int64_t)demux->filepos,(int64_t)demux->filepos);
861 num_elementary_packets100=0; // requires for re-sync!
862 num_elementary_packets101=0; // requires for re-sync!
863 } else demux->synced=0;
864 } // else
865 if(demux->synced>=2){
866 ret=demux_mpg_read_packet(demux,head);
867 if(!ret)
868 if(--max_packs==0){
869 demux->stream->eof=1;
870 mp_tmsg(MSGT_DEMUX,MSGL_ERR,"demux: File doesn't contain the selected audio or video stream.\n");
871 return 0;
873 if(demux->synced==3) demux->synced=(ret==1)?2:0; // PES detect
874 } else {
875 update_stats(head);
876 if(head>=0x100 && head<0x1B0)
877 mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... elementary video packet found: %03X\n",head);
878 else if((head>=0x1C0 && head<0x1F0) || head==0x1BD)
879 mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... PES packet found: %03X\n",head);
881 if(((num_elementary_packets100>50 && num_elementary_packets101>50) ||
882 (num_elementary_packetsPES>50)) && skipped>4000000){
883 mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be ES/PES stream...\n");
884 demux->stream->eof=1;
885 break;
887 if(num_mp3audio_packets>100 && num_elementary_packets100<10){
888 mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be MP3 stream...\n");
889 demux->stream->eof=1;
890 break;
893 } while(ret!=1);
894 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux: %d bad bytes skipped\n",skipped);
895 if(demux->stream->eof){
896 mp_msg(MSGT_DEMUX,MSGL_V,"MPEG Stream reached EOF\n");
897 return 0;
899 return 1;
902 static void demux_seek_mpg(demuxer_t *demuxer, float rel_seek_secs,
903 float audio_delay, int flags)
905 demux_stream_t *d_audio=demuxer->audio;
906 demux_stream_t *d_video=demuxer->video;
907 sh_audio_t *sh_audio=d_audio->sh;
908 sh_video_t *sh_video=d_video->sh;
909 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
910 int precision = 1;
911 float oldpts = 0;
912 off_t oldpos = demuxer->filepos;
913 float newpts = 0;
914 off_t newpos = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : oldpos;
916 if(mpg_d)
917 oldpts = mpg_d->last_pts;
918 newpts = (flags & SEEK_ABSOLUTE) ? 0.0 : oldpts;
919 //================= seek in MPEG ==========================
920 //calculate the pts to seek to
921 if(flags & SEEK_FACTOR) {
922 if (mpg_d && mpg_d->first_to_final_pts_len > 0.0)
923 newpts += mpg_d->first_to_final_pts_len * rel_seek_secs;
924 else
925 newpts += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * oldpts / oldpos;
926 } else
927 newpts += rel_seek_secs;
928 if (newpts < 0) newpts = 0;
930 if(flags&SEEK_FACTOR){
931 // float seek 0..1
932 newpos+=(demuxer->movi_end-demuxer->movi_start)*rel_seek_secs;
933 } else {
934 // time seek (secs)
935 if (mpg_d && mpg_d->has_valid_timestamps) {
936 if (mpg_d->first_to_final_pts_len > 0.0)
937 newpos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / mpg_d->first_to_final_pts_len;
938 else if (oldpts > 0.0)
939 newpos += rel_seek_secs * (oldpos - demuxer->movi_start) / oldpts;
940 } else if(!sh_video || !sh_video->i_bps) // unspecified or VBR
941 newpos+=2324*75*rel_seek_secs; // 174.3 kbyte/sec
942 else
943 newpos+=sh_video->i_bps*rel_seek_secs;
946 while (1) {
947 if(newpos<demuxer->movi_start){
948 if(demuxer->stream->type!=STREAMTYPE_VCD) demuxer->movi_start=0; // for VCD
949 if(newpos<demuxer->movi_start) newpos=demuxer->movi_start;
952 stream_seek(demuxer->stream,newpos);
954 // re-sync video:
955 videobuf_code_len=0; // reset ES stream buffer
957 ds_fill_buffer(d_video);
958 if(sh_audio){
959 ds_fill_buffer(d_audio);
962 while(1){
963 int i;
964 if(sh_audio && !d_audio->eof && d_video->pts && d_audio->pts){
965 float a_pts=d_audio->pts;
966 a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
967 if(d_video->pts>a_pts){
968 skip_audio_frame(sh_audio); // sync audio
969 continue;
972 if(!sh_video) break;
973 i=sync_video_packet(d_video);
974 if(sh_video->format == mmioFOURCC('W', 'V', 'C', '1')) {
975 if(i==0x10E || i==0x10F) //entry point or sequence header
976 break;
977 } else
978 if(sh_video->format == 0x10000004) { //mpeg4
979 if(i==0x1B6) { //vop (frame) startcode
980 int pos = videobuf_len;
981 if(!read_video_packet(d_video)) break; // EOF
982 if((videobuffer[pos+4] & 0x3F) == 0) break; //I-frame
984 } else if(sh_video->format == 0x10000005){ //h264
985 if((i & ~0x60) == 0x105) break;
986 } else { //default mpeg1/2
987 if(i==0x1B3 || i==0x1B8) break; // found it!
989 if(!i || !skip_video_packet(d_video)) break; // EOF?
991 if(!mpg_d)
992 break;
993 if (!precision || abs(newpts - mpg_d->last_pts) < 0.5 || (mpg_d->last_pts == oldpts)) break;
994 if ((newpos - oldpos) * (mpg_d->last_pts - oldpts) < 0) { // invalid timestamps
995 mpg_d->has_valid_timestamps = 0;
996 break;
998 precision--;
999 //prepare another seek because we are off by more than 0.5s
1000 if(mpg_d) {
1001 newpos += (newpts - mpg_d->last_pts) * (newpos - oldpos) / (mpg_d->last_pts - oldpts);
1002 demux_flush(demuxer);
1003 demuxer->stream->eof=0; // clear eof flag
1004 d_video->eof=0;
1005 d_audio->eof=0;
1010 static int demux_mpg_control(demuxer_t *demuxer, int cmd, void *arg)
1012 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
1014 switch(cmd) {
1015 case DEMUXER_CTRL_GET_TIME_LENGTH:
1016 if(stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, arg) != STREAM_UNSUPPORTED) {
1017 mp_msg(MSGT_DEMUXER,MSGL_DBG2,"\r\nDEMUX_MPG_CTRL, (%.3f)\r\n", *((double*)arg));
1018 return DEMUXER_CTRL_GUESS;
1020 if (mpg_d && mpg_d->has_valid_timestamps) {
1021 *((double *)arg)=(double)mpg_d->first_to_final_pts_len;
1022 return DEMUXER_CTRL_OK;
1024 return DEMUXER_CTRL_DONTKNOW;
1026 case DEMUXER_CTRL_GET_PERCENT_POS:
1027 if (mpg_d && mpg_d->has_valid_timestamps && mpg_d->first_to_final_pts_len > 0.0) {
1028 *((int *)arg)=(int)(100 * (mpg_d->last_pts-mpg_d->first_pts) / mpg_d->first_to_final_pts_len);
1029 return DEMUXER_CTRL_OK;
1031 return DEMUXER_CTRL_DONTKNOW;
1033 case DEMUXER_CTRL_SWITCH_AUDIO:
1034 if(! (mpg_d && mpg_d->num_a_streams > 1 && demuxer->audio && demuxer->audio->sh))
1035 return DEMUXER_CTRL_NOTIMPL;
1036 else {
1037 demux_stream_t *d_audio = demuxer->audio;
1038 sh_audio_t *sh_audio = d_audio->sh;
1039 sh_audio_t *sh_a = sh_audio;
1040 int i;
1041 if(!sh_audio)
1042 return DEMUXER_CTRL_NOTIMPL;
1043 if (*((int*)arg) < 0)
1045 for (i = 0; i < mpg_d->num_a_streams; i++) {
1046 if (d_audio->id == mpg_d->a_stream_ids[i]) break;
1048 i = (i+1) % mpg_d->num_a_streams;
1049 sh_a = (sh_audio_t*)demuxer->a_streams[mpg_d->a_stream_ids[i]];
1051 else {
1052 for (i = 0; i < mpg_d->num_a_streams; i++)
1053 if (*((int*)arg) == mpg_d->a_stream_ids[i]) break;
1054 if (i < mpg_d->num_a_streams)
1055 sh_a = (sh_audio_t*)demuxer->a_streams[*((int*)arg)];
1057 if (i < mpg_d->num_a_streams && d_audio->id != mpg_d->a_stream_ids[i]) {
1058 d_audio->id = mpg_d->a_stream_ids[i];
1059 d_audio->sh = sh_a;
1060 ds_free_packs(d_audio);
1063 *((int*)arg) = demuxer->audio->id;
1064 return DEMUXER_CTRL_OK;
1066 default:
1067 return DEMUXER_CTRL_NOTIMPL;
1072 static int demux_mpg_pes_probe(demuxer_t *demuxer) {
1073 demuxer->synced = 3;
1074 return (demux_mpg_probe(demuxer) == DEMUXER_TYPE_MPEG_PS) ? DEMUXER_TYPE_MPEG_PES : 0;
1078 static demuxer_t* demux_mpg_es_open(demuxer_t* demuxer)
1080 sh_video_t *sh_video=NULL;
1082 demuxer->audio->sh = NULL; // ES streams has no audio channel
1083 demuxer->video->sh = new_sh_video(demuxer,0); // create dummy video stream header, id=0
1084 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1086 return demuxer;
1089 static demuxer_t *demux_mpg_gxf_open(demuxer_t *demuxer) {
1090 demuxer->audio->sh = NULL;
1091 demuxer->video->sh = new_sh_video(demuxer,0);
1092 ((sh_video_t *)demuxer->video->sh)->ds = demuxer->video;
1093 demuxer->priv = (void *) 0xffffffff;
1094 return demuxer;
1097 static demuxer_t* demux_mpg_ps_open(demuxer_t* demuxer)
1099 sh_audio_t *sh_audio=NULL;
1100 sh_video_t *sh_video=NULL;
1102 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1104 if(demuxer->audio->id!=-2) {
1105 if(!ds_fill_buffer(demuxer->audio)){
1106 mp_msg(MSGT_DEMUXER, MSGL_INFO, "MPEG: %s",
1107 mp_gtext("No audio stream found -> no sound.\n"));
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,