mirror of
https://github.com/mpv-player/mpv
synced 2024-12-25 00:02:13 +00:00
added support for other codecs (mpeg4/h264/aac) in mpeg-ps parsing the PSM
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@14924 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
d13d95f551
commit
c596f03a8a
@ -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 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
|
||||
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 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
|
||||
|
||||
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 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
|
||||
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 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
|
||||
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 @@ void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,int flags){
|
||||
}
|
||||
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
|
||||
|
@ -46,7 +46,7 @@ enum {
|
||||
|
||||
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 @@ if((d_video->demuxer->file_format == DEMUXER_TYPE_PVA) ||
|
||||
)
|
||||
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 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
|
||||
|
||||
*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 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user