libfaad2: cosmetics: Make local_changes.diff apply cleanly
[mplayer.git] / libmpdemux / demux_mpg.c
blobddc5d218ddf0cef9db65ee7f1c095510387105d7
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 "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 static int mpeg_pts_error=0;
62 off_t ps_probe = 0;
64 static int parse_psm(demuxer_t *demux, int len) {
65 unsigned char c, id, type;
66 unsigned int plen, prog_len, es_map_len;
67 mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
69 mp_dbg(MSGT_DEMUX,MSGL_V, "PARSE_PSM, len=%d\n", len);
70 if(! len || len > 1018)
71 return 0;
73 c = stream_read_char(demux->stream);
74 if(! (c & 0x80)) {
75 stream_skip(demux->stream, len - 1); //not yet valid, discard
76 return 0;
78 stream_skip(demux->stream, 1);
79 prog_len = stream_read_word(demux->stream); //length of program descriptors
80 stream_skip(demux->stream, prog_len); //.. that we ignore
81 es_map_len = stream_read_word(demux->stream); //length of elementary streams map
82 es_map_len = FFMIN(es_map_len, len - prog_len - 8); //sanity check
83 while(es_map_len > 0) {
84 type = stream_read_char(demux->stream);
85 id = stream_read_char(demux->stream);
86 if(id >= 0xB0 && id <= 0xEF && priv) {
87 int idoffset = id - 0xB0;
88 switch(type) {
89 case 0x1:
90 priv->es_map[idoffset] = VIDEO_MPEG1;
91 break;
92 case 0x2:
93 priv->es_map[idoffset] = VIDEO_MPEG2;
94 break;
95 case 0x3:
96 case 0x4:
97 priv->es_map[idoffset] = AUDIO_MP2;
98 break;
99 case 0x0f:
100 case 0x11:
101 priv->es_map[idoffset] = AUDIO_AAC;
102 break;
103 case 0x10:
104 priv->es_map[idoffset] = VIDEO_MPEG4;
105 break;
106 case 0x1b:
107 priv->es_map[idoffset] = VIDEO_H264;
108 break;
109 case 0x81:
110 priv->es_map[idoffset] = AUDIO_A52;
111 break;
113 mp_dbg(MSGT_DEMUX,MSGL_V, "PSM ES, id=0x%x, type=%x, stype: %x\n", id, type, priv->es_map[idoffset]);
115 plen = stream_read_word(demux->stream); //length of elementary stream descriptors
116 plen = FFMIN(plen, es_map_len); //sanity check
117 stream_skip(demux->stream, plen); //skip descriptors for now
118 es_map_len -= 4 + plen;
120 stream_skip(demux->stream, 4); //skip crc32
121 return 1;
124 // 500000 is a wild guess
125 #define TIMESTAMP_PROBE_LEN 500000
127 //MAX_PTS_DIFF_FOR_CONSECUTIVE denotes the maximum difference
128 //between two pts to consider them consecutive
129 //1.0 is a wild guess
130 #define MAX_PTS_DIFF_FOR_CONSECUTIVE 1.0
132 //returns the first pts found within TIME_STAMP_PROBE_LEN bytes after stream_pos in demuxer's stream.
133 //if no pts is found or an error occurs, -1.0 is returned.
134 //Packs are freed.
135 static float read_first_mpeg_pts_at_position(demuxer_t* demuxer, off_t stream_pos)
137 stream_t *s = demuxer->stream;
138 mpg_demuxer_t *mpg_d = demuxer->priv;
139 float pts = -1.0; //the pts to return;
140 float found_pts1; //the most recently found pts
141 float found_pts2; //the pts found before found_pts1
142 float found_pts3; //the pts found before found_pts2
143 int found = 0;
145 if(!mpg_d || stream_pos < 0)
146 return pts;
148 found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts;
149 stream_seek(s, stream_pos);
151 //We look for pts.
152 //However, we do not stop at the first found one, as timestamps may reset
153 //Therefore, we seek until we found three consecutive
154 //pts within MAX_PTS_DIFF_FOR_CONSECUTIVE.
156 while(found<3 && !s->eof
157 && (fabsf(found_pts2-found_pts1) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
158 && (fabsf(found_pts3-found_pts2) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
159 && (stream_tell(s) < stream_pos + TIMESTAMP_PROBE_LEN)
160 && ds_fill_buffer(demuxer->video))
162 if(mpg_d->last_pts != found_pts1)
164 if(!found)
165 found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts; //the most recently found pts
166 else
168 found_pts3 = found_pts2;
169 found_pts2 = found_pts1;
170 found_pts1 = mpg_d->last_pts;
172 found++;
176 if(found == 3) pts = found_pts3;
178 //clean up from searching of first pts;
179 demux_flush(demuxer);
181 return pts;
184 /// Open an mpg physical stream
185 static demuxer_t* demux_mpg_open(demuxer_t* demuxer) {
186 stream_t *s = demuxer->stream;
187 mpg_demuxer_t* mpg_d;
189 if (!ds_fill_buffer(demuxer->video)) return 0;
190 mpg_d = calloc(1,sizeof(mpg_demuxer_t));
191 if(mpg_d)
193 demuxer->priv = mpg_d;
194 mpg_d->last_pts = -1.0;
195 mpg_d->first_pts = -1.0;
197 //if seeking is allowed set has_valid_timestamps if appropriate
198 if(demuxer->seekable
199 && (demuxer->stream->type == STREAMTYPE_FILE
200 || demuxer->stream->type == STREAMTYPE_VCD)
201 && demuxer->movi_start != demuxer-> movi_end
204 //We seek to the beginning of the stream, to somewhere in the
205 //middle, and to the end of the stream, while remembering the pts
206 //at each of the three positions. With these pts, we check whether
207 //or not the pts are "linear enough" to justify seeking by the pts
208 //of the stream
210 //The position where the stream is now
211 off_t pos = stream_tell(s);
212 float first_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_start);
213 if(first_pts != -1.0)
215 float middle_pts = read_first_mpeg_pts_at_position(demuxer, (demuxer->movi_end + demuxer->movi_start)/2);
216 if(middle_pts != -1.0)
218 float final_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_end - TIMESTAMP_PROBE_LEN);
219 if(final_pts != -1.0)
221 // found proper first, middle, and final pts.
222 float proportion = (middle_pts-first_pts==0) ? -1 : (final_pts-middle_pts)/(middle_pts-first_pts);
223 // if they are linear enough set has_valid_timestamps
224 if((0.5 < proportion) && (proportion < 2))
226 mpg_d->first_pts = first_pts;
227 mpg_d->first_to_final_pts_len = final_pts - first_pts;
228 mpg_d->has_valid_timestamps = 1;
234 //Cleaning up from seeking in stream
235 demuxer->stream->eof=0;
236 demuxer->video->eof=0;
237 demuxer->audio->eof=0;
239 stream_seek(s,pos);
240 ds_fill_buffer(demuxer->video);
241 } // if ( demuxer->seekable )
242 } // if ( mpg_d )
243 return demuxer;
246 static void demux_close_mpg(demuxer_t* demuxer) {
247 mpg_demuxer_t* mpg_d = demuxer->priv;
248 if (mpg_d) free(mpg_d);
252 static unsigned long long read_mpeg_timestamp(stream_t *s,int c){
253 unsigned int d,e;
254 unsigned long long pts;
255 d=stream_read_word(s);
256 e=stream_read_word(s);
257 if( ((c&1)!=1) || ((d&1)!=1) || ((e&1)!=1) ){
258 ++mpeg_pts_error;
259 return 0; // invalid pts
261 pts=(((uint64_t)((c>>1)&7))<<30)|((d>>1)<<15)|(e>>1);
262 mp_dbg(MSGT_DEMUX,MSGL_DBG3," pts {%"PRIu64"}",pts);
263 return pts;
266 static void new_audio_stream(demuxer_t *demux, int aid){
267 if(!demux->a_streams[aid]){
268 mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demux->priv;
269 sh_audio_t* sh_a;
270 new_sh_audio(demux,aid);
271 sh_a = (sh_audio_t*)demux->a_streams[aid];
272 sh_a->needs_parsing = 1;
273 switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id)
274 case 0x00: sh_a->format=0x50;break; // mpeg
275 case 0xA0: sh_a->format=0x10001;break; // dvd pcm
276 case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts
277 else sh_a->format=0x2000;break; // ac3
279 //evo files
280 if((aid & 0xC0) == 0xC0) sh_a->format=0x2000;
281 else if(aid >= 0x98 && aid <= 0x9f) sh_a->format=0x2001;
282 if (mpg_d) mpg_d->a_stream_ids[mpg_d->num_a_streams++] = aid;
284 if(demux->audio->id==-1) demux->audio->id=aid;
287 static int demux_mpg_read_packet(demuxer_t *demux,int id){
288 int d;
289 int len;
290 int set_pts=0; // !=0 iff pts has been set to a proper value
291 unsigned char c=0;
292 unsigned long long pts=0;
293 unsigned long long dts=0;
294 int l;
295 int pes_ext2_subid=-1;
296 double stream_pts = MP_NOPTS_VALUE;
297 demux_stream_t *ds=NULL;
298 demux_packet_t* dp;
299 mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
301 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_read_packet: %X\n",id);
303 // if(id==0x1F0){
304 // demux->synced=0; // force resync after 0x1F0
305 // return -1;
308 // if(id==0x1BA) packet_start_pos=stream_tell(demux->stream);
309 if((id<0x1BC || id>=0x1F0) && id != 0x1FD) return -1;
310 if(id==0x1BE) return -1; // padding stream
311 if(id==0x1BF) return -1; // private2
313 len=stream_read_word(demux->stream);
314 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"PACKET len=%d",len);
315 // if(len==62480){ demux->synced=0;return -1;} /* :) */
316 if(len==0 || len>MAX_PS_PACKETSIZE){
317 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS packet len: %d\n",len);
318 return -2; // invalid packet !!!!!!
321 mpeg_pts_error=0;
323 if(id==0x1BC) {
324 parse_psm(demux, len);
325 return 0;
328 while(len>0){ // Skip stuFFing bytes
329 c=stream_read_char(demux->stream);
330 --len;
331 if(c!=0xFF)break;
333 if((c>>6)==1){ // Read (skip) STD scale & size value
334 // printf(" STD_scale=%d",(c>>5)&1);
335 d=((c&0x1F)<<8)|stream_read_char(demux->stream);
336 len-=2;
337 // printf(" STD_size=%d",d);
338 c=stream_read_char(demux->stream);
340 // Read System-1 stream timestamps:
341 if((c>>4)==2){
342 pts=read_mpeg_timestamp(demux->stream,c);
343 set_pts=1;
344 len-=4;
345 } else
346 if((c>>4)==3){
347 pts=read_mpeg_timestamp(demux->stream,c);
348 c=stream_read_char(demux->stream);
349 if((c>>4)!=1) pts=0; //printf("{ERROR4}");
350 else set_pts = 1;
351 dts=read_mpeg_timestamp(demux->stream,c);
352 len-=4+1+4;
353 } else
354 if((c>>6)==2){
355 int pts_flags;
356 int hdrlen;
357 int parse_ext2;
358 // System-2 (.VOB) stream:
359 c=stream_read_char(demux->stream);
360 pts_flags=c>>6;
361 parse_ext2 = (id == 0x1FD) && ((c & 0x3F) == 1);
362 c=stream_read_char(demux->stream);
363 hdrlen=c;
364 len-=2;
365 mp_dbg(MSGT_DEMUX,MSGL_DBG3," hdrlen=%d (len=%d)",hdrlen,len);
366 if(hdrlen>len){ mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: invalid header length \n"); return -1;}
367 if(pts_flags==2 && hdrlen>=5){
368 c=stream_read_char(demux->stream);
369 pts=read_mpeg_timestamp(demux->stream,c);
370 set_pts=1;
371 len-=5;hdrlen-=5;
372 } else
373 if(pts_flags==3 && hdrlen>=10){
374 c=stream_read_char(demux->stream);
375 pts=read_mpeg_timestamp(demux->stream,c);
376 set_pts=1;
377 c=stream_read_char(demux->stream);
378 dts=read_mpeg_timestamp(demux->stream,c);
379 len-=10;hdrlen-=10;
381 len-=hdrlen;
382 if(parse_ext2 && hdrlen>=3) {
383 c=stream_read_char(demux->stream);
384 hdrlen--;
386 if((c & 0x0F) != 0x0F) {
387 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: pes_extension_flag2 not set, discarding pes packet\n");
388 return -1;
390 if(c & 0x80) { //pes_private_data_flag
391 if(hdrlen<16) {
392 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pes_private_data bytes: %d < 16, discarding pes packet\n", hdrlen);
393 return -1;
395 stream_skip(demux->stream, 16);
396 hdrlen-=16;
398 if(c & 0x40) { //pack_header_field_flag
399 int l = stream_read_char(demux->stream);
400 if(l < 0) //couldn't read from the stream?
401 return -1;
402 hdrlen--;
403 if(l < 0 || hdrlen < l) {
404 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pack_header bytes: hdrlen: %d < skip: %d, discarding pes packet\n",
405 hdrlen, l);
406 return -1;
408 stream_skip(demux->stream, l);
409 hdrlen-=l;
411 if(c & 0x20) { //program_packet_sequence_counter_flag
412 if(hdrlen < 2) {
413 mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough program_packet bytes: hdrlen: %d, discarding pes packet\n", hdrlen);
414 return -1;
416 stream_skip(demux->stream, 2);
417 hdrlen-=2;
419 if(c & 0x10) {
420 //STD
421 stream_skip(demux->stream, 2);
422 hdrlen-=2;
424 c=stream_read_char(demux->stream); //pes_extension2 flag
425 hdrlen--;
426 if(c!=0x81) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown pes_extension2 format, len is > 1 \n"); return -1;}
427 c=stream_read_char(demux->stream); //pes_extension2 payload === substream id
428 hdrlen--;
429 if(c<0x55 || c>0x5F) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown vc1 substream_id: 0x%x \n", c); return -1;}
430 pes_ext2_subid=c;
432 if(hdrlen>0)
433 stream_skip(demux->stream,hdrlen); // skip header and stuffing bytes
435 if(id==0x1FD && pes_ext2_subid!=-1) {
436 //==== EVO VC1 STREAMS ===//
437 if(!demux->v_streams[pes_ext2_subid]) new_sh_video(demux,pes_ext2_subid);
438 if(demux->video->id==-1) demux->video->id=pes_ext2_subid;
439 if(demux->video->id==pes_ext2_subid){
440 ds=demux->video;
441 if(!ds->sh) ds->sh=demux->v_streams[pes_ext2_subid];
442 if(priv && ds->sh) {
443 sh_video_t *sh = (sh_video_t *)ds->sh;
444 sh->format = mmioFOURCC('W', 'V', 'C', '1');
448 //============== DVD Audio sub-stream ======================
449 if(id==0x1BD){
450 int aid, rawa52 = 0;
451 off_t tmppos;
452 unsigned int tmp;
454 tmppos = stream_tell(demux->stream);
455 tmp = stream_read_word(demux->stream);
456 stream_seek(demux->stream, tmppos);
457 /// vdr stores A52 without the 4 header bytes, so we have to check this condition first
458 if(tmp == 0x0B77) {
459 aid = 128;
460 rawa52 = 1;
462 else {
463 aid=stream_read_char(demux->stream);--len;
464 if(len<3) return -1; // invalid audio packet
467 // AID:
468 // 0x20..0x3F subtitle
469 // 0x80..0x87 and 0xC0..0xCF AC3 audio
470 // 0x88..0x8F and 0x98..0x9F DTS audio
471 // 0xA0..0xBF PCM audio
473 if((aid & 0xE0) == 0x20){
474 // subtitle:
475 aid&=0x1F;
477 if(!demux->s_streams[aid]){
478 sh_sub_t *sh = new_sh_sub(demux, aid);
479 if (sh) sh->type = 'v';
480 mp_msg(MSGT_DEMUX,MSGL_V,"==> Found subtitle: %d\n",aid);
483 if(demux->sub->id > -1)
484 demux->sub->id &= 0x1F;
485 if(!demux->opts->sub_lang && demux->sub->id == -1)
486 demux->sub->id = aid;
487 if(demux->sub->id==aid){
488 ds=demux->sub;
490 } else if((aid >= 0x80 && aid <= 0x8F) || (aid >= 0x98 && aid <= 0xAF) || (aid >= 0xC0 && aid <= 0xCF)) {
492 // aid=128+(aid&0x7F);
493 // aid=0x80..0xBF
494 new_audio_stream(demux, aid);
495 if(demux->audio->id==aid){
496 int type;
497 ds=demux->audio;
498 if(!ds->sh) ds->sh=demux->a_streams[aid];
499 // READ Packet: Skip additional audio header data:
500 if(!rawa52) {
501 c=stream_read_char(demux->stream);//num of frames
502 type=stream_read_char(demux->stream);//startpos hi
503 type=(type<<8)|stream_read_char(demux->stream);//startpos lo
504 // printf("\r[%02X][%04X]",c,type);
505 len-=3;
507 if((aid&0xE0)==0xA0 && len>=3){
508 unsigned char* hdr;
509 // save audio header as codecdata!
510 if(!((sh_audio_t*)(ds->sh))->codecdata_len){
511 ((sh_audio_t*)(ds->sh))->codecdata=malloc(3);
512 ((sh_audio_t*)(ds->sh))->codecdata_len=3;
514 hdr=((sh_audio_t*)(ds->sh))->codecdata;
515 // read LPCM header:
516 // emphasis[1], mute[1], rvd[1], frame number[5]:
517 hdr[0]=stream_read_char(demux->stream);
518 // printf(" [%01X:%02d]",c>>5,c&31);
519 // quantization[2],freq[2],rvd[1],channels[3]
520 hdr[1]=stream_read_char(demux->stream);
521 // printf("[%01X:%01X] ",c>>4,c&15);
522 // dynamic range control (0x80=off):
523 hdr[2]=stream_read_char(demux->stream);
524 // printf("[%02X] ",c);
525 len-=3;
526 if(len<=0) mp_msg(MSGT_DEMUX,MSGL_V,"End of packet while searching for PCM header\n");
528 // printf(" \n");
529 } // if(demux->audio->id==aid)
531 } else mp_msg(MSGT_DEMUX,MSGL_V,"Unknown 0x1BD substream: 0x%02X \n",aid);
532 } //if(id==0x1BD)
533 } else {
534 if(c!=0x0f){
535 mp_msg(MSGT_DEMUX,MSGL_V," {ERROR5,c=%d} \n",c);
536 return -1; // invalid packet !!!!!!
539 if(mpeg_pts_error) mp_msg(MSGT_DEMUX,MSGL_V," {PTS_err:%d} \n",mpeg_pts_error);
540 mp_dbg(MSGT_DEMUX,MSGL_DBG3," => len=%d\n",len);
542 // if(len<=0 || len>MAX_PS_PACKETSIZE) return -1; // Invalid packet size
543 if(len<=0 || len>MAX_PS_PACKETSIZE){
544 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS data len: %d\n",len);
545 return -1; // invalid packet !!!!!!
548 if(id>=0x1C0 && id<=0x1DF){
549 // mpeg audio
550 int aid=id-0x1C0;
551 new_audio_stream(demux, aid);
552 if(demux->audio->id==aid){
553 ds=demux->audio;
554 if(!ds->sh) ds->sh=demux->a_streams[aid];
555 if(priv && ds->sh) {
556 sh_audio_t *sh = (sh_audio_t *)ds->sh;
557 if(priv->es_map[id - 0x1B0])
558 sh->format = priv->es_map[id - 0x1B0];
559 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
562 } else
563 if(id>=0x1E0 && id<=0x1EF){
564 // mpeg video
565 int aid=id-0x1E0;
566 if(!demux->v_streams[aid]) new_sh_video(demux,aid);
567 if(demux->video->id==-1) demux->video->id=aid;
568 if(demux->video->id==aid){
569 ds=demux->video;
570 if(!ds->sh) ds->sh=demux->v_streams[aid];
571 if(priv && ds->sh) {
572 sh_video_t *sh = (sh_video_t *)ds->sh;
573 if(priv->es_map[id - 0x1B0]) {
574 sh->format = priv->es_map[id - 0x1B0];
575 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
581 if(ds){
582 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Read %d data bytes from packet %04X\n",len,id);
583 // printf("packet start = 0x%X \n",stream_tell(demux->stream)-packet_start_pos);
585 dp=new_demux_packet(len);
586 if(!dp) {
587 mp_dbg(MSGT_DEMUX,MSGL_ERR,"DEMUX_MPG ERROR: couldn't create demux_packet(%d bytes)\n",len);
588 stream_skip(demux->stream,len);
589 return 0;
591 l = stream_read(demux->stream,dp->buffer,len);
592 if(l<len)
593 resize_demux_packet(dp, l);
594 len = l;
595 if(set_pts)
596 dp->pts=pts/90000.0f;
597 dp->pos=demux->filepos;
599 workaround:
600 set dp->stream_pts only when feeding the video stream, or strangely interleaved files
601 (such as SWIII) will show strange alternations in the stream time, wildly going
602 back and forth
604 if(ds == demux->video && stream_control(demux->stream, STREAM_CTRL_GET_CURRENT_TIME,(void *)&stream_pts)!=STREAM_UNSUPPORTED)
605 dp->stream_pts = stream_pts;
606 ds_add_packet(ds,dp);
607 if (demux->priv && set_pts) ((mpg_demuxer_t*)demux->priv)->last_pts = pts/90000.0f;
608 // if(ds==demux->sub) parse_dvdsub(ds->last->buffer,ds->last->len);
609 return 1;
611 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Skipping %d data bytes from packet %04X\n",len,id);
612 if(len<=2356) stream_skip(demux->stream,len);
613 return 0;
616 static int num_elementary_packets100=0;
617 static int num_elementary_packets101=0;
618 static int num_elementary_packets12x=0;
619 static int num_elementary_packets1B6=0;
620 static int num_elementary_packetsPES=0;
621 static int num_mpeg12_startcode=0;
622 static int num_h264_slice=0; //combined slice
623 static int num_h264_dpa=0; //DPA Slice
624 static int num_h264_dpb=0; //DPB Slice
625 static int num_h264_dpc=0; //DPC Slice
626 static int num_h264_idr=0; //IDR Slice
627 static int num_h264_sps=0;
628 static int num_h264_pps=0;
630 static int num_mp3audio_packets=0;
632 static void clear_stats(void)
634 num_elementary_packets100=0;
635 num_elementary_packets101=0;
636 num_elementary_packets1B6=0;
637 num_elementary_packets12x=0;
638 num_elementary_packetsPES=0;
639 num_mpeg12_startcode=0;
640 num_h264_slice=0; //combined slice
641 num_h264_dpa=0; //DPA Slice
642 num_h264_dpb=0; //DPB Slice
643 num_h264_dpc=0; //DPC Slice
644 num_h264_idr=0; //IDR Slice
645 num_h264_sps=0;
646 num_h264_pps=0;
647 num_mp3audio_packets=0;
650 //assumes demuxer->synced < 2
651 static inline void update_stats(int head)
653 if(head==0x1B6) ++num_elementary_packets1B6;
654 else if(head==0x1B3 || head==0x1B8) ++num_mpeg12_startcode;
655 else if(head==0x100) ++num_elementary_packets100;
656 else if(head==0x101) ++num_elementary_packets101;
657 else if(head==0x1BD || (0x1C0<=head && head<=0x1EF))
658 num_elementary_packetsPES++;
659 else if(head>=0x120 && head<=0x12F) ++num_elementary_packets12x;
660 if(head>=0x100 && head<0x1B0)
662 if((head&~0x60) == 0x101) ++num_h264_slice;
663 else if((head&~0x60) == 0x102) ++num_h264_dpa;
664 else if((head&~0x60) == 0x103) ++num_h264_dpb;
665 else if((head&~0x60) == 0x104) ++num_h264_dpc;
666 else if((head&~0x60) == 0x105 && head != 0x105) ++num_h264_idr;
667 else if((head&~0x60) == 0x107 && head != 0x107) ++num_h264_sps;
668 else if((head&~0x60) == 0x108 && head != 0x108) ++num_h264_pps;
672 static int demux_mpg_probe(demuxer_t *demuxer) {
673 int pes=1;
674 int tmp;
675 off_t tmppos;
676 int file_format = DEMUXER_TYPE_UNKNOWN;
678 tmppos=stream_tell(demuxer->stream);
679 tmp=stream_read_dword(demuxer->stream);
680 if(tmp==0x1E0 || tmp==0x1C0) {
681 tmp=stream_read_word(demuxer->stream);
682 if(tmp>1 && tmp<=2048) pes=0; // demuxer->synced=3; // PES...
684 stream_seek(demuxer->stream,tmppos);
686 clear_stats();
688 if(demux_mpg_open(demuxer))
689 file_format=DEMUXER_TYPE_MPEG_PS;
690 else {
691 mp_msg(MSGT_DEMUX,MSGL_V,"MPEG packet stats: p100: %d p101: %d p1B6: %d p12x: %d sli: %d a: %d b: %d c: %d idr: %d sps: %d pps: %d PES: %d MP3: %d, synced: %d\n",
692 num_elementary_packets100,num_elementary_packets101,
693 num_elementary_packets1B6,num_elementary_packets12x,
694 num_h264_slice, num_h264_dpa,
695 num_h264_dpb, num_h264_dpc=0,
696 num_h264_idr, num_h264_sps=0,
697 num_h264_pps,
698 num_elementary_packetsPES,num_mp3audio_packets, demuxer->synced);
700 //MPEG packet stats: p100: 458 p101: 458 PES: 0 MP3: 1103 (.m2v)
701 if(num_mp3audio_packets>50 && num_mp3audio_packets>2*num_elementary_packets100
702 && abs(num_elementary_packets100-num_elementary_packets101)>2)
703 return file_format;
705 // some hack to get meaningfull error messages to our unhappy users:
706 if(num_mpeg12_startcode>=2 && num_elementary_packets100>=2 && num_elementary_packets101>=2 &&
707 abs(num_elementary_packets101+8-num_elementary_packets100)<16) {
708 if(num_elementary_packetsPES>=4 && num_elementary_packetsPES>=num_elementary_packets100-4) {
709 return file_format;
711 file_format=DEMUXER_TYPE_MPEG_ES; // <-- hack is here :)
712 } else
713 // fuzzy mpeg4-es detection. do NOT enable without heavy testing of mpeg formats detection!
714 if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
715 num_elementary_packetsPES==0 && num_elementary_packets100<=num_elementary_packets12x &&
716 demuxer->synced<2) {
717 file_format=DEMUXER_TYPE_MPEG4_ES;
718 } else
719 // fuzzy h264-es detection. do NOT enable without heavy testing of mpeg formats detection!
720 if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
721 /* FIXME num_h264_sps>=1 && */ num_h264_pps>=1 && num_h264_idr>=1 &&
722 num_elementary_packets1B6==0 && num_elementary_packetsPES==0 &&
723 demuxer->synced<2) {
724 file_format=DEMUXER_TYPE_H264_ES;
725 } else
727 if(demuxer->synced==2)
728 mp_msg(MSGT_DEMUXER, MSGL_ERR, "MPEG: %s",
729 mp_gtext("Missing video stream!? Contact the author, it may be a bug :(\n"));
730 else
731 mp_tmsg(MSGT_DEMUXER,MSGL_V,"Not MPEG System Stream format... (maybe Transport Stream?)\n");
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_tmsg(MSGT_DEMUX,MSGL_ERR,"demux: File doesn't contain the selected audio or video stream.\n");
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, (%.3f)\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: %s",
1108 mp_gtext("No audio stream found -> no sound.\n"));
1109 demuxer->audio->sh=NULL;
1110 } else {
1111 sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
1115 if(!sh_video->format && ps_probe > 0) {
1116 int head;
1117 off_t pos = stream_tell(demuxer->stream);
1119 clear_stats();
1120 do {
1121 head=sync_video_packet(demuxer->video);
1122 if(!head) break;
1123 update_stats(head);
1124 skip_video_packet(demuxer->video);
1125 } while(stream_tell(demuxer->stream) < pos + ps_probe && !demuxer->stream->eof);
1127 ds_free_packs(demuxer->video);
1128 demuxer->stream->eof=0;
1129 stream_seek(demuxer->stream, pos);
1130 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",
1131 num_elementary_packets100, num_elementary_packets101,
1132 num_elementary_packets1B6, num_elementary_packets12x,
1133 num_h264_slice, num_h264_dpa, num_h264_dpb, num_h264_dpc,
1134 num_h264_idr, num_h264_sps, num_h264_pps);
1136 if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
1137 num_elementary_packets100<=num_elementary_packets12x)
1138 sh_video->format = 0x10000004;
1139 else if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
1140 num_h264_sps>=1 && num_h264_pps>=1 && num_h264_idr>=1 &&
1141 num_elementary_packets1B6==0)
1142 sh_video->format = 0x10000005;
1143 else sh_video->format = 0x10000002;
1146 return demuxer;
1150 const demuxer_desc_t demuxer_desc_mpeg_ps = {
1151 "MPEG PS demuxer",
1152 "mpegps",
1153 "MPEG-PS",
1154 "Arpi?",
1155 "Mpeg",
1156 DEMUXER_TYPE_MPEG_PS,
1157 0, // unsafe autodetect
1158 demux_mpg_probe,
1159 demux_mpg_fill_buffer,
1160 demux_mpg_ps_open,
1161 demux_close_mpg,
1162 demux_seek_mpg,
1163 demux_mpg_control,
1167 const demuxer_desc_t demuxer_desc_mpeg_pes = {
1168 "MPEG PES demuxer",
1169 "mpegpes",
1170 "MPEG-PES",
1171 "Arpi?",
1172 "Mpeg",
1173 DEMUXER_TYPE_MPEG_PES,
1174 0, // unsafe autodetect
1175 demux_mpg_pes_probe,
1176 demux_mpg_fill_buffer,
1177 demux_mpg_ps_open,
1178 demux_close_mpg,
1179 demux_seek_mpg,
1180 demux_mpg_control,
1184 const demuxer_desc_t demuxer_desc_mpeg_gxf = {
1185 "MPEG ES in GXF demuxer",
1186 "mpeggxf",
1187 "MPEG-ES in GXF",
1188 "Reimar Doeffinger",
1189 "Mpeg",
1190 DEMUXER_TYPE_MPEG_GXF,
1191 0, // hack autodetection
1192 NULL,
1193 demux_mpg_gxf_fill_buffer,
1194 demux_mpg_gxf_open,
1195 NULL,
1196 NULL,
1197 NULL
1200 const demuxer_desc_t demuxer_desc_mpeg_es = {
1201 "MPEG ES demuxer",
1202 "mpeges",
1203 "MPEG-ES",
1204 "Arpi?",
1205 "Mpeg",
1206 DEMUXER_TYPE_MPEG_ES,
1207 0, // hack autodetection
1208 NULL,
1209 demux_mpg_es_fill_buffer,
1210 demux_mpg_es_open,
1211 demux_close_mpg,
1212 demux_seek_mpg,
1213 demux_mpg_control,
1217 const demuxer_desc_t demuxer_desc_mpeg4_es = {
1218 "MPEG4 ES demuxer",
1219 "mpeg4es",
1220 "MPEG-ES",
1221 "Arpi?",
1222 "Mpeg",
1223 DEMUXER_TYPE_MPEG4_ES,
1224 0, // hack autodetection
1225 NULL,
1226 demux_mpg_es_fill_buffer,
1227 demux_mpg_es_open,
1228 demux_close_mpg,
1229 demux_seek_mpg,
1230 demux_mpg_control,
1234 const demuxer_desc_t demuxer_desc_h264_es = {
1235 "H.264 ES demuxer",
1236 "h264es",
1237 "H264-ES",
1238 "Arpi?",
1239 "Mpeg",
1240 DEMUXER_TYPE_H264_ES,
1241 0, // hack autodetection
1242 NULL,
1243 demux_mpg_es_fill_buffer,
1244 demux_mpg_es_open,
1245 demux_close_mpg,
1246 demux_seek_mpg,
1247 demux_mpg_control,