Revert the xvmc part of r30422: VCR2 at least worked with xvmc at some point.
[mplayer/glamo.git] / libmpdemux / demux_mpg.c
blob72ab2a9b27aa1034000731ca11ac2c1f1f8115e7
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 int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
818 unsigned int head=0;
819 int skipped=0;
820 int max_packs=256; // 512kbyte
821 int ret=0;
823 // System stream
825 demux->filepos=stream_tell(demux->stream);
826 #if 1
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 #endif
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_msg(MSGT_DEMUX,MSGL_ERR,MSGTR_DoesntContainSelectedStream);
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 void skip_audio_frame(sh_audio_t *sh_audio);
904 void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,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 int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){
1011 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
1013 switch(cmd) {
1014 case DEMUXER_CTRL_GET_TIME_LENGTH:
1015 if(stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, arg) != STREAM_UNSUPPORTED) {
1016 mp_msg(MSGT_DEMUXER,MSGL_DBG2,"\r\nDEMUX_MPG_CTRL, (%.3lf)\r\n", *((double*)arg));
1017 return DEMUXER_CTRL_GUESS;
1019 if (mpg_d && mpg_d->has_valid_timestamps) {
1020 *((double *)arg)=(double)mpg_d->first_to_final_pts_len;
1021 return DEMUXER_CTRL_OK;
1023 return DEMUXER_CTRL_DONTKNOW;
1025 case DEMUXER_CTRL_GET_PERCENT_POS:
1026 if (mpg_d && mpg_d->has_valid_timestamps && mpg_d->first_to_final_pts_len > 0.0) {
1027 *((int *)arg)=(int)(100 * (mpg_d->last_pts-mpg_d->first_pts) / mpg_d->first_to_final_pts_len);
1028 return DEMUXER_CTRL_OK;
1030 return DEMUXER_CTRL_DONTKNOW;
1032 case DEMUXER_CTRL_SWITCH_AUDIO:
1033 if(! (mpg_d && mpg_d->num_a_streams > 1 && demuxer->audio && demuxer->audio->sh))
1034 return DEMUXER_CTRL_NOTIMPL;
1035 else {
1036 demux_stream_t *d_audio = demuxer->audio;
1037 sh_audio_t *sh_audio = d_audio->sh;
1038 sh_audio_t *sh_a = sh_audio;
1039 int i;
1040 if(!sh_audio)
1041 return DEMUXER_CTRL_NOTIMPL;
1042 if (*((int*)arg) < 0)
1044 for (i = 0; i < mpg_d->num_a_streams; i++) {
1045 if (d_audio->id == mpg_d->a_stream_ids[i]) break;
1047 i = (i+1) % mpg_d->num_a_streams;
1048 sh_a = (sh_audio_t*)demuxer->a_streams[mpg_d->a_stream_ids[i]];
1050 else {
1051 for (i = 0; i < mpg_d->num_a_streams; i++)
1052 if (*((int*)arg) == mpg_d->a_stream_ids[i]) break;
1053 if (i < mpg_d->num_a_streams)
1054 sh_a = (sh_audio_t*)demuxer->a_streams[*((int*)arg)];
1056 if (i < mpg_d->num_a_streams && d_audio->id != mpg_d->a_stream_ids[i]) {
1057 d_audio->id = mpg_d->a_stream_ids[i];
1058 d_audio->sh = sh_a;
1059 ds_free_packs(d_audio);
1062 *((int*)arg) = demuxer->audio->id;
1063 return DEMUXER_CTRL_OK;
1065 default:
1066 return DEMUXER_CTRL_NOTIMPL;
1071 static int demux_mpg_pes_probe(demuxer_t *demuxer) {
1072 demuxer->synced = 3;
1073 return (demux_mpg_probe(demuxer) == DEMUXER_TYPE_MPEG_PS) ? DEMUXER_TYPE_MPEG_PES : 0;
1077 static demuxer_t* demux_mpg_es_open(demuxer_t* demuxer)
1079 sh_video_t *sh_video=NULL;
1081 demuxer->audio->sh = NULL; // ES streams has no audio channel
1082 demuxer->video->sh = new_sh_video(demuxer,0); // create dummy video stream header, id=0
1083 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1085 return demuxer;
1088 static demuxer_t *demux_mpg_gxf_open(demuxer_t *demuxer) {
1089 demuxer->audio->sh = NULL;
1090 demuxer->video->sh = new_sh_video(demuxer,0);
1091 ((sh_video_t *)demuxer->video->sh)->ds = demuxer->video;
1092 demuxer->priv = (void *) 0xffffffff;
1093 return demuxer;
1096 static demuxer_t* demux_mpg_ps_open(demuxer_t* demuxer)
1098 sh_audio_t *sh_audio=NULL;
1099 sh_video_t *sh_video=NULL;
1101 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1103 if(demuxer->audio->id!=-2) {
1104 if(!ds_fill_buffer(demuxer->audio)){
1105 mp_msg(MSGT_DEMUXER,MSGL_INFO,"MPEG: " MSGTR_MissingAudioStream);
1106 demuxer->audio->sh=NULL;
1107 } else {
1108 sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
1112 if(!sh_video->format && ps_probe > 0) {
1113 int head;
1114 off_t pos = stream_tell(demuxer->stream);
1116 clear_stats();
1117 do {
1118 head=sync_video_packet(demuxer->video);
1119 if(!head) break;
1120 update_stats(head);
1121 skip_video_packet(demuxer->video);
1122 } while(stream_tell(demuxer->stream) < pos + ps_probe && !demuxer->stream->eof);
1124 ds_free_packs(demuxer->video);
1125 demuxer->stream->eof=0;
1126 stream_seek(demuxer->stream, pos);
1127 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",
1128 num_elementary_packets100, num_elementary_packets101,
1129 num_elementary_packets1B6, num_elementary_packets12x,
1130 num_h264_slice, num_h264_dpa, num_h264_dpb, num_h264_dpc,
1131 num_h264_idr, num_h264_sps, num_h264_pps);
1133 if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
1134 num_elementary_packets100<=num_elementary_packets12x)
1135 sh_video->format = 0x10000004;
1136 else if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
1137 num_h264_sps>=1 && num_h264_pps>=1 && num_h264_idr>=1 &&
1138 num_elementary_packets1B6==0)
1139 sh_video->format = 0x10000005;
1140 else sh_video->format = 0x10000002;
1143 return demuxer;
1147 const demuxer_desc_t demuxer_desc_mpeg_ps = {
1148 "MPEG PS demuxer",
1149 "mpegps",
1150 "MPEG-PS",
1151 "Arpi?",
1152 "Mpeg",
1153 DEMUXER_TYPE_MPEG_PS,
1154 0, // unsafe autodetect
1155 demux_mpg_probe,
1156 demux_mpg_fill_buffer,
1157 demux_mpg_ps_open,
1158 demux_close_mpg,
1159 demux_seek_mpg,
1160 demux_mpg_control,
1164 const demuxer_desc_t demuxer_desc_mpeg_pes = {
1165 "MPEG PES demuxer",
1166 "mpegpes",
1167 "MPEG-PES",
1168 "Arpi?",
1169 "Mpeg",
1170 DEMUXER_TYPE_MPEG_PES,
1171 0, // unsafe autodetect
1172 demux_mpg_pes_probe,
1173 demux_mpg_fill_buffer,
1174 demux_mpg_ps_open,
1175 demux_close_mpg,
1176 demux_seek_mpg,
1177 demux_mpg_control,
1181 const demuxer_desc_t demuxer_desc_mpeg_gxf = {
1182 "MPEG ES in GXF demuxer",
1183 "mpeggxf",
1184 "MPEG-ES in GXF",
1185 "Reimar Doeffinger",
1186 "Mpeg",
1187 DEMUXER_TYPE_MPEG_GXF,
1188 0, // hack autodetection
1189 NULL,
1190 demux_mpg_gxf_fill_buffer,
1191 demux_mpg_gxf_open,
1192 NULL,
1193 NULL,
1194 NULL
1197 const demuxer_desc_t demuxer_desc_mpeg_es = {
1198 "MPEG ES demuxer",
1199 "mpeges",
1200 "MPEG-ES",
1201 "Arpi?",
1202 "Mpeg",
1203 DEMUXER_TYPE_MPEG_ES,
1204 0, // hack autodetection
1205 NULL,
1206 demux_mpg_es_fill_buffer,
1207 demux_mpg_es_open,
1208 demux_close_mpg,
1209 demux_seek_mpg,
1210 demux_mpg_control,
1214 const demuxer_desc_t demuxer_desc_mpeg4_es = {
1215 "MPEG4 ES demuxer",
1216 "mpeg4es",
1217 "MPEG-ES",
1218 "Arpi?",
1219 "Mpeg",
1220 DEMUXER_TYPE_MPEG4_ES,
1221 0, // hack autodetection
1222 NULL,
1223 demux_mpg_es_fill_buffer,
1224 demux_mpg_es_open,
1225 demux_close_mpg,
1226 demux_seek_mpg,
1227 demux_mpg_control,
1231 const demuxer_desc_t demuxer_desc_h264_es = {
1232 "H.264 ES demuxer",
1233 "h264es",
1234 "H264-ES",
1235 "Arpi?",
1236 "Mpeg",
1237 DEMUXER_TYPE_H264_ES,
1238 0, // hack autodetection
1239 NULL,
1240 demux_mpg_es_fill_buffer,
1241 demux_mpg_es_open,
1242 demux_close_mpg,
1243 demux_seek_mpg,
1244 demux_mpg_control,