# HG changeset patch # User nicodvb # Date 1231074771 0 # Node ID 6fc5386a8b6b1ff406251fe997c91b0dc1c45ef2 # Parent 6e8d3a955f64f9b9bce2cee5989008b7e71fb2f9 added support for manual audio substream selection out of 0xFD PES streams (Blueray, multistream in the same pid) diff -r 6e8d3a955f64 -r 6fc5386a8b6b DOCS/man/en/mplayer.1 --- a/DOCS/man/en/mplayer.1 Sun Jan 04 13:08:13 2009 +0000 +++ b/DOCS/man/en/mplayer.1 Sun Jan 04 13:12:51 2009 +0000 @@ -1166,6 +1166,16 @@ (if present) with the chosen audio stream. . .TP +.B \-ausid (also see \-alang) +Select audio substream channel. +Currently the valid range is 0x55..0x75 and applies only to MPEG-TS when handled +by the native demuxer (not by libavformat). +The format type may not be correctly identified because of how this information +(or lack thereof) is embedded in the stream, but it will demux correctly the +audio streams when multiple substreams are present. +MPlayer prints the available substream IDs when run with \-identify. +. +.TP .B \-alang (also see \-aid) Specify a priority list of audio languages to use. Different container formats employ different language codes. diff -r 6e8d3a955f64 -r 6fc5386a8b6b cfg-common-opts.h --- a/cfg-common-opts.h Sun Jan 04 13:08:13 2009 +0000 +++ b/cfg-common-opts.h Sun Jan 04 13:12:51 2009 +0000 @@ -123,6 +123,7 @@ // select audio/video/subtitle stream {"aid", &audio_id, CONF_TYPE_INT, CONF_RANGE, 0, 8190, NULL}, + {"ausid", &audio_substream_id, CONF_TYPE_INT, 0, 0, 0, NULL}, {"vid", &video_id, CONF_TYPE_INT, CONF_RANGE, 0, 8190, NULL}, {"sid", &dvdsub_id, CONF_TYPE_INT, CONF_RANGE, 0, 8190, NULL}, {"novideo", &video_id, CONF_TYPE_FLAG, 0, -1, -2, NULL}, diff -r 6e8d3a955f64 -r 6fc5386a8b6b cfg-common.h --- a/cfg-common.h Sun Jan 04 13:08:13 2009 +0000 +++ b/cfg-common.h Sun Jan 04 13:12:51 2009 +0000 @@ -53,6 +53,7 @@ extern int ts_prog; extern int ts_keep_broken; extern off_t ts_probe; +extern int audio_substream_id; extern off_t ps_probe; #include "stream/tv.h" diff -r 6e8d3a955f64 -r 6fc5386a8b6b libmpdemux/demux_ts.c --- a/libmpdemux/demux_ts.c Sun Jan 04 13:08:13 2009 +0000 +++ b/libmpdemux/demux_ts.c Sun Jan 04 13:12:51 2009 +0000 @@ -59,6 +59,7 @@ int ts_prog; int ts_keep_broken=0; off_t ts_probe = 0; +int audio_substream_id = -1; extern char *dvdsub_lang, *audio_lang; //for -alang typedef enum @@ -1280,6 +1281,67 @@ return m; } +//this function parses the extension fields in the PES header and returns the substream_id, or -1 in case of errors +static int parse_pes_extension_fields(unsigned char *p, int pkt_len) +{ + int skip; + unsigned char flags; + + if(!(p[7] & 0x1)) //no extension_field + return -1; + skip = 9; + if(p[7] & 0x80) + { + skip += 5; + if(p[7] & 0x40) + skip += 5; + } + if(p[7] & 0x20) //escr_flag + skip += 6; + if(p[7] & 0x10) //es_rate_flag + skip += 3; + if(p[7] & 0x08)//dsm_trick_mode is unsupported, skip + { + skip = 0;//don't let's parse the extension fields + } + if(p[7] & 0x04) //additional_copy_info + skip += 1; + if(p[7] & 0x02) //pes_crc_flag + skip += 2; + if(skip >= pkt_len) //too few bytes + return -1; + flags = p[skip]; + skip++; + if(flags & 0x80) //pes_private_data_flag + skip += 16; + if(skip >= pkt_len) + return -1; + if(flags & 0x40) //pack_header_field_flag + { + unsigned char l = p[skip]; + skip += l; + } + if(flags & 0x20) //program_packet_sequence_counter + skip += 2; + if(flags & 0x10) //p_std + skip += 2; + if(skip >= pkt_len) + return -1; + if(flags & 0x01) //finally the long desired pes_extension2 + { + unsigned char l = p[skip]; //ext2 flag+len + skip++; + if((l == 0x81) && (skip < pkt_len)) + { + int ssid = p[skip]; + mp_msg(MSGT_IDENTIFY, MSGL_V, "SUBSTREAM_ID=%d (0x%02X)\n", ssid, ssid); + return ssid; + } + } + + return -1; +} + static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es, int32_t type_from_pmt, pmt_t *pmt, int pid) { unsigned char *p; @@ -1343,6 +1405,13 @@ mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_ts: illegal value for PES_header_data_length (0x%02x)\n", header_len); return 0; } + + if(stream_id==0xfd) + { + int ssid = parse_pes_extension_fields(p, pkt_len); + if((audio_substream_id!=-1) && (ssid != audio_substream_id)) + return 0; + } p += header_len + 9; packet_len -= header_len + 3;