Mercurial > mplayer.hg
changeset 14923:658fc109eefc
added support for other codecs (mpeg4/h264/aac) in mpeg-ps parsing the PSM
author | nicodvb |
---|---|
date | Sun, 06 Mar 2005 21:10:01 +0000 |
parents | ed06939c5217 |
children | 7f386d84805f |
files | libmpdemux/demux_mpg.c libmpdemux/video.c |
diffstat | 2 files changed, 109 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpdemux/demux_mpg.c Sun Mar 06 17:55:31 2005 +0000 +++ b/libmpdemux/demux_mpg.c Sun Mar 06 21:10:01 2005 +0000 @@ -17,14 +17,85 @@ //#define MAX_PS_PACKETSIZE 2048 #define MAX_PS_PACKETSIZE (224*1024) +#define UNKNOWN 0 +#define VIDEO_MPEG1 0x10000001 +#define VIDEO_MPEG2 0x10000002 +#define VIDEO_MPEG4 0x10000004 +#define VIDEO_H264 0x10000005 +#define AUDIO_MP2 0x50 +#define AUDIO_A52 0x2000 +#define AUDIO_LPCM_BE 0x10001 +#define AUDIO_AAC mmioFOURCC('M', 'P', '4', 'A') + typedef struct mpg_demuxer { float last_pts; float final_pts; int has_valid_timestamps; + unsigned int es_map[0x40]; //es map of stream types (associated to the pes id) from 0xb0 to 0xef } mpg_demuxer_t; static int mpeg_pts_error=0; +static int parse_psm(demuxer_t *demux, int len) { + unsigned char c, id, type; + unsigned int plen, prog_len, es_map_len; + mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv; + + mp_dbg(MSGT_DEMUX,MSGL_V, "PARSE_PSM, len=%d\n", len); + if(! len) + return 0; + + c = stream_read_char(demux->stream); + if(! (c & 0x80)) { + stream_skip(demux->stream, len - 1); //not yet valid, discard + return 0; + } + stream_skip(demux->stream, 1); + prog_len = stream_read_word(demux->stream); //length of program descriptors + stream_skip(demux->stream, prog_len); //.. that we ignore + es_map_len = stream_read_word(demux->stream); //length of elementary streams map + es_map_len = min(es_map_len, len - prog_len - 8); //sanity check + while(es_map_len > 0) { + type = stream_read_char(demux->stream); + id = stream_read_char(demux->stream); + if(id >= 0xB0 && id <= 0xEF && priv) { + int idoffset = id - 0xB0; + switch(type) { + case 0x1: + priv->es_map[idoffset] = VIDEO_MPEG1; + break; + case 0x2: + priv->es_map[idoffset] = VIDEO_MPEG2; + break; + case 0x3: + case 0x4: + priv->es_map[idoffset] = AUDIO_MP2; + break; + case 0x0f: + case 0x11: + priv->es_map[idoffset] = AUDIO_AAC; + break; + case 0x10: + priv->es_map[idoffset] = VIDEO_MPEG4; + break; + case 0x1b: + priv->es_map[idoffset] = VIDEO_H264; + break; + case 0x81: + priv->es_map[idoffset] = AUDIO_A52; + break; + } + mp_dbg(MSGT_DEMUX,MSGL_V, "PSM ES, id=0x%x, type=%x, stype: %x\n", id, type, priv->es_map[idoffset]); + } + plen = stream_read_word(demux->stream); //length of elementary stream descriptors + plen = min(plen, es_map_len); //sanity check + stream_skip(demux->stream, plen); //skip descriptors for now + es_map_len -= 4 + plen; + } + stream_skip(demux->stream, 4); //skip crc32 + return 1; +} + /// Open an mpg physical stream int demux_mpg_open(demuxer_t* demuxer) { stream_t *s = demuxer->stream; @@ -90,6 +161,7 @@ unsigned int pts=0; unsigned int dts=0; demux_stream_t *ds=NULL; + mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv; mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_read_packet: %X\n",id); @@ -113,6 +185,11 @@ mpeg_pts_error=0; + if(id==0x1BC) { + parse_psm(demux, len); + return 0; + } + while(len>0){ // Skip stuFFing bytes c=stream_read_char(demux->stream);--len; if(c!=0xFF)break; @@ -255,6 +332,12 @@ if(demux->audio->id==aid){ ds=demux->audio; if(!ds->sh) ds->sh=demux->a_streams[aid]; + if(priv && ds->sh) { + sh_audio_t *sh = (sh_audio_t *)ds->sh; + if(priv->es_map[id - 0x1B0]) + sh->format = priv->es_map[id - 0x1B0]; + mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]); + } } } else if(id>=0x1E0 && id<=0x1EF){ @@ -265,6 +348,13 @@ if(demux->video->id==aid){ ds=demux->video; if(!ds->sh) ds->sh=demux->v_streams[aid]; + if(priv && ds->sh) { + sh_video_t *sh = (sh_video_t *)ds->sh; + if(priv->es_map[id - 0x1B0]) { + sh->format = priv->es_map[id - 0x1B0]; + mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]); + } + } } } @@ -479,7 +569,11 @@ } i=sync_video_packet(d_video); if(sh_video->format == 0x10000004) { //mpeg4 - if(i==0x1B6) break; //vop (frame) startcode + if(i==0x1B6) { //vop (frame) startcode + int pos = videobuf_len; + if(!read_video_packet(d_video)) break; // EOF + if((videobuffer[pos+4] & 0x3F) == 0) break; //I-frame + } } else if(sh_video->format == 0x10000005){ //h264 if((i & ~0x60) == 0x101 || (i & ~0x60) == 0x102 || (i & ~0x60) == 0x105) break; } else { //default mpeg1/2
--- a/libmpdemux/video.c Sun Mar 06 17:55:31 2005 +0000 +++ b/libmpdemux/video.c Sun Mar 06 21:10:01 2005 +0000 @@ -46,7 +46,7 @@ if((d_video->demuxer->file_format == DEMUXER_TYPE_PVA) || (d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_ES) || - (d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_PS) || + (d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_PS && ((! sh_video->format) || (sh_video->format==0x10000001) || (sh_video->format==0x10000002))) || (d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_TY) || (d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_TS && ((sh_video->format==0x10000001) || (sh_video->format==0x10000002))) #ifdef STREAMING_LIVE_DOT_COM @@ -55,11 +55,13 @@ ) video_codec = VIDEO_MPEG12; else if((d_video->demuxer->file_format == DEMUXER_TYPE_MPEG4_ES) || - ((d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000004)) + ((d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000004)) || + ((d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_PS) && (sh_video->format==0x10000004)) ) video_codec = VIDEO_MPEG4; else if((d_video->demuxer->file_format == DEMUXER_TYPE_H264_ES) || - ((d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000005)) + ((d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000005)) || + ((d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_PS) && (sh_video->format==0x10000005)) ) video_codec = VIDEO_H264; else @@ -400,7 +402,8 @@ *start=NULL; - if(demuxer->file_format==DEMUXER_TYPE_MPEG_ES || demuxer->file_format==DEMUXER_TYPE_MPEG_PS + if(demuxer->file_format==DEMUXER_TYPE_MPEG_ES || + (demuxer->file_format==DEMUXER_TYPE_MPEG_PS && ((! sh_video->format) || (sh_video->format==0x10000001) || (sh_video->format==0x10000002))) || demuxer->file_format==DEMUXER_TYPE_PVA || ((demuxer->file_format==DEMUXER_TYPE_MPEG_TS) && ((sh_video->format==0x10000001) || (sh_video->format==0x10000002))) || demuxer->file_format==DEMUXER_TYPE_MPEG_TY @@ -493,17 +496,22 @@ telecine=1; } - } else if((demuxer->file_format==DEMUXER_TYPE_MPEG4_ES) || ((demuxer->file_format==DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000004))){ + } else if((demuxer->file_format==DEMUXER_TYPE_MPEG4_ES) || ((demuxer->file_format==DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000004)) || + ((demuxer->file_format==DEMUXER_TYPE_MPEG_PS) && (sh_video->format==0x10000004)) + ){ // while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){ int i=sync_video_packet(d_video); + if(!i) return -1; if(!read_video_packet(d_video)) return -1; // EOF if(i==0x1B6) break; } *start=videobuffer; in_size=videobuf_len; videobuf_len=0; - } else if(demuxer->file_format==DEMUXER_TYPE_H264_ES || ((demuxer->file_format==DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000005))){ + } else if(demuxer->file_format==DEMUXER_TYPE_H264_ES || ((demuxer->file_format==DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000005)) || + ((demuxer->file_format==DEMUXER_TYPE_MPEG_PS) && (sh_video->format==0x10000005)) + ){ // while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){ int i=sync_video_packet(d_video);