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
This commit is contained in:
nicodvb 2009-01-04 13:12:51 +00:00
parent 5efcd82cb1
commit 480e153e2f
4 changed files with 81 additions and 0 deletions

View File

@ -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.

View File

@ -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},

View File

@ -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"

View File

@ -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;