diff options
author | nicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2009-01-04 13:12:51 +0000 |
---|---|---|
committer | nicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2009-01-04 13:12:51 +0000 |
commit | 480e153e2fde22007c2ef6d4cab3a0d0589e2917 (patch) | |
tree | c8145db1bcc156aa85e194bd0cb1994f0de586a9 | |
parent | 5efcd82cb15de12f241b4838214fead28943734f (diff) | |
download | mpv-480e153e2fde22007c2ef6d4cab3a0d0589e2917.tar.bz2 mpv-480e153e2fde22007c2ef6d4cab3a0d0589e2917.tar.xz |
added support for manual audio substream selection out of 0xFD PES streams (Blueray, multistream in the same pid)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@28245 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r-- | DOCS/man/en/mplayer.1 | 10 | ||||
-rw-r--r-- | cfg-common-opts.h | 1 | ||||
-rw-r--r-- | cfg-common.h | 1 | ||||
-rw-r--r-- | libmpdemux/demux_ts.c | 69 |
4 files changed, 81 insertions, 0 deletions
diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1 index c19c20fe63..9b8f8a3935 100644 --- a/DOCS/man/en/mplayer.1 +++ b/DOCS/man/en/mplayer.1 @@ -1166,6 +1166,16 @@ When playing an MPEG-TS stream, MPlayer/\:MEncoder will use the first program (if present) with the chosen audio stream. . .TP +.B \-ausid <ID> (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 <language code[,language code,...]> (also see \-aid) Specify a priority list of audio languages to use. Different container formats employ different language codes. diff --git a/cfg-common-opts.h b/cfg-common-opts.h index f9badb64b5..65d7a413ea 100644 --- a/cfg-common-opts.h +++ b/cfg-common-opts.h @@ -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 --git a/cfg-common.h b/cfg-common.h index c69deb2cbf..9a4e258f35 100644 --- a/cfg-common.h +++ b/cfg-common.h @@ -53,6 +53,7 @@ extern int demuxer_type, audio_demuxer_type, sub_demuxer_type; 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 --git a/libmpdemux/demux_ts.c b/libmpdemux/demux_ts.c index c0924d9ecf..3de0ce404b 100644 --- a/libmpdemux/demux_ts.c +++ b/libmpdemux/demux_ts.c @@ -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 @@ static int mp4_parse_sl_packet(pmt_t *pmt, uint8_t *buf, uint16_t packet_len, in 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 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es, 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; |