mirror of
https://github.com/mpv-player/mpv
synced 2025-03-30 23:38:10 +00:00
added support for ac3 in non-pes aligned private1 streams; removed useless and commented code
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12613 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
00a4249b4a
commit
89f39f93e4
@ -47,6 +47,7 @@
|
||||
#define TS_MAX_PROBE_SIZE 2000000 /* dont forget to change this in cfg-common.h too */
|
||||
#define NUM_CONSECUTIVE_TS_PACKETS 32
|
||||
#define NUM_CONSECUTIVE_AUDIO_PACKETS 348
|
||||
#define MAX_A52_FRAME_SIZE 3840
|
||||
|
||||
|
||||
int ts_prog;
|
||||
@ -65,7 +66,8 @@ typedef enum
|
||||
AUDIO_LPCM_BE = 0x10001,
|
||||
AUDIO_AAC = mmioFOURCC('M', 'P', '4', 'A'),
|
||||
SPU_DVD = 0x3000000,
|
||||
SPU_DVB = 0x3000001
|
||||
SPU_DVB = 0x3000001,
|
||||
PES_PRIVATE1 = 0xBD00000
|
||||
} es_stream_type_t;
|
||||
|
||||
|
||||
@ -371,6 +373,36 @@ typedef struct {
|
||||
off_t probe;
|
||||
} tsdemux_init_t;
|
||||
|
||||
|
||||
//second stage: returns the count of A52 syncwords found
|
||||
static int a52_check(char *buf, int len)
|
||||
{
|
||||
int cnt, frame_length, flags, sample_rate, bit_rate, ok;
|
||||
|
||||
cnt = ok = 0;
|
||||
if(len < 8)
|
||||
return 0;
|
||||
|
||||
while(cnt < len - 7)
|
||||
{
|
||||
if(buf[cnt] == 0x0B && buf[cnt+1] == 0x77)
|
||||
{
|
||||
frame_length = a52_syncinfo(&buf[cnt], &flags, &sample_rate, &bit_rate);
|
||||
if(frame_length>=7 && frame_length<=3840)
|
||||
{
|
||||
cnt += frame_length;
|
||||
ok++;
|
||||
}
|
||||
}
|
||||
else
|
||||
cnt++;
|
||||
}
|
||||
|
||||
mp_msg(MSGT_DEMUXER, MSGL_V, "A52_CHECK(%d input bytes), found %d frame syncwords of %d bytes length\n", len, ok, frame_length);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param)
|
||||
{
|
||||
int video_found = 0, audio_found = 0, sub_found = 0, i, num_packets = 0, req_apid, req_vpid, req_spid;
|
||||
@ -380,6 +412,10 @@ static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param)
|
||||
ES_stream_t es;
|
||||
unsigned char tmp[TS_FEC_PACKET_SIZE];
|
||||
ts_priv_t *priv = (ts_priv_t*) demuxer->priv;
|
||||
struct {
|
||||
char *buf;
|
||||
int pos;
|
||||
} pes_priv1[8192], *pptr;
|
||||
|
||||
priv->last_pid = 8192; //invalid pid
|
||||
|
||||
@ -388,6 +424,7 @@ static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param)
|
||||
req_spid = param->spid;
|
||||
|
||||
has_tables = 0;
|
||||
bzero(pes_priv1, sizeof(pes_priv1));
|
||||
init_pos = stream_tell(demuxer->stream);
|
||||
mp_msg(MSGT_DEMUXER, MSGL_INFO, "PROBING UP TO %llu, PROG: %d\n", (uint64_t) param->probe, param->prog);
|
||||
while((pos <= init_pos + param->probe) && (! demuxer->stream->eof))
|
||||
@ -395,6 +432,24 @@ static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param)
|
||||
pos = stream_tell(demuxer->stream);
|
||||
if(ts_parse(demuxer, &es, tmp, 1))
|
||||
{
|
||||
//Non PES-aligned A52 audio may escape detection if PMT is not present;
|
||||
//in this case we try to find at least 3 A52 syncwords
|
||||
if((es.type == PES_PRIVATE1) && (! audio_found))
|
||||
{
|
||||
pptr = &pes_priv1[es.pid];
|
||||
pptr->buf = (char*) realloc(pptr->buf, pptr->pos + es.size);
|
||||
if(pptr->buf != NULL)
|
||||
{
|
||||
memcpy(&(pptr->buf[ pptr->pos ]), es.start, es.size);
|
||||
pptr->pos += es.size;
|
||||
if(a52_check(pptr->buf, pptr->pos) > 2)
|
||||
{
|
||||
param->atype = AUDIO_A52;
|
||||
es.type = AUDIO_A52;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is_audio = ((es.type == AUDIO_MP2) || (es.type == AUDIO_A52) || (es.type == AUDIO_LPCM_BE) || (es.type == AUDIO_AAC));
|
||||
is_video = ((es.type == VIDEO_MPEG1) || (es.type == VIDEO_MPEG2) || (es.type == VIDEO_MPEG4));
|
||||
is_sub = ((es.type == SPU_DVD) || (es.type == SPU_DVB));
|
||||
@ -535,6 +590,16 @@ static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param)
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<8192; i++)
|
||||
{
|
||||
if(pes_priv1[i].buf != NULL)
|
||||
{
|
||||
free(pes_priv1[i].buf);
|
||||
pes_priv1[i].buf = NULL;
|
||||
pes_priv1[i].pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(video_found)
|
||||
mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG%d(pid=%d)...", (param->vtype == VIDEO_MPEG1 ? 1 : (param->vtype == VIDEO_MPEG2 ? 2 : 4)), param->vpid);
|
||||
else
|
||||
@ -546,7 +611,7 @@ static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param)
|
||||
}
|
||||
|
||||
if(param->atype == AUDIO_MP2)
|
||||
mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO MP2(pid=%d)", param->apid);
|
||||
mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO MPA(pid=%d)", param->apid);
|
||||
else if(param->atype == AUDIO_A52)
|
||||
mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO A52(pid=%d)", param->apid);
|
||||
else if(param->atype == AUDIO_LPCM_BE)
|
||||
@ -562,7 +627,7 @@ static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param)
|
||||
}
|
||||
|
||||
if(param->stype == SPU_DVD || param->stype == SPU_DVB)
|
||||
mp_msg(MSGT_DEMUXER, MSGL_INFO, " SUB DVx(pid=%d) ", param->spid);
|
||||
mp_msg(MSGT_DEMUXER, MSGL_INFO, " SUB %s(pid=%d) ", (param->stype==SPU_DVD ? "DVD" : "DVB"), param->spid);
|
||||
else
|
||||
{
|
||||
param->stype = UNKNOWN;
|
||||
@ -739,12 +804,7 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
|
||||
uint32_t header_len;
|
||||
int64_t pts;
|
||||
uint32_t stream_id;
|
||||
uint32_t pkt_len;
|
||||
|
||||
//THE FOLLOWING CODE might be needed in the future:
|
||||
//uint8_t es_rate_flag, escr_flag, pts_flag;
|
||||
//int64_t escr, dts;
|
||||
//uint32_t es_rate;
|
||||
uint32_t pkt_len, pes_is_aligned;
|
||||
|
||||
//Here we are always at the start of a PES packet
|
||||
mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2(%p, %d): \n", buf, (uint32_t) packet_len);
|
||||
@ -781,6 +841,7 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
|
||||
}
|
||||
|
||||
es->payload_size = (p[4] << 8 | p[5]);
|
||||
pes_is_aligned = (p[6] & 4);
|
||||
|
||||
stream_id = p[3];
|
||||
|
||||
@ -798,33 +859,6 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
|
||||
else
|
||||
es->pts = 0.0f;
|
||||
|
||||
/*
|
||||
CODE TO CALCULATE ES_RATE AND ESCR, ACTUALLY UNUSED BUT POSSIBLY NEEDED IN THE FUTURE
|
||||
|
||||
pts_flag = ((p[7] & 0xc0) >> 6) & 3;
|
||||
escr_flag = p[7] & 0x20;
|
||||
es_rate_flag = p[7] & 0x10;
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "pes_parse: ES_RATE_FLAG=%d, ESCR_FLAG=%d, PTS_FLAG=%d, byte=%02X\n", es_rate_flag, escr_flag, pts_flag, p[7]);
|
||||
|
||||
|
||||
if(es_rate_flag)
|
||||
{
|
||||
char *base;
|
||||
int bytes = 0;
|
||||
|
||||
if(pts_flag == 2)
|
||||
bytes += 5;
|
||||
else if(pts_flag == 3)
|
||||
bytes += 10;
|
||||
|
||||
if(escr_flag)
|
||||
bytes += 6;
|
||||
|
||||
base = p[8+bytes];
|
||||
es_rate = ((base[0] & 0x7f) << 8) | (base[1] << 8) | (base[0] & 0xfe);
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "demux_ts: ES_RATE=%d)\n", es_rate*50);
|
||||
}
|
||||
*/
|
||||
|
||||
header_len = p[8];
|
||||
|
||||
@ -849,14 +883,9 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
|
||||
|
||||
if (stream_id == 0xbd)
|
||||
{
|
||||
int track; //, spu_id;
|
||||
|
||||
mp_msg(MSGT_DEMUX, MSGL_DBG3, "pes_parse2: audio buf = %02X %02X %02X %02X %02X %02X %02X %02X, 80: %d\n",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[0] & 0x80);
|
||||
|
||||
track = p[0] & 0x0F;
|
||||
mp_msg(MSGT_DEMUX, MSGL_DBG2, "A52 TRACK: %d\n", track);
|
||||
|
||||
|
||||
/*
|
||||
* we check the descriptor tag first because some stations
|
||||
@ -880,7 +909,7 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
|
||||
}
|
||||
/* SPU SUBS */
|
||||
else if(type_from_pmt == SPU_DVB ||
|
||||
(p[0] == 0x20)) // && p[1] == 0x00))
|
||||
((p[0] == 0x20) && pes_is_aligned)) // && p[1] == 0x00))
|
||||
{
|
||||
es->start = p;
|
||||
es->size = packet_len;
|
||||
@ -889,7 +918,7 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if ((p[0] & 0xE0) == 0x20) //SPU_DVD
|
||||
else if (pes_is_aligned && ((p[0] & 0xE0) == 0x20)) //SPU_DVD
|
||||
{
|
||||
//DVD SUBS
|
||||
es->start = p+1;
|
||||
@ -909,7 +938,7 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if ((p[0]&0xf0) == 0xa0)
|
||||
else if (pes_is_aligned && ((p[0]&0xf0) == 0xa0))
|
||||
{
|
||||
int pcm_offset;
|
||||
|
||||
@ -927,6 +956,16 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
|
||||
es->type = AUDIO_LPCM_BE;
|
||||
es->payload_size -= packet_len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_msg(MSGT_DEMUX, MSGL_DBG2, "PES_PRIVATE1\n");
|
||||
es->start = p;
|
||||
es->size = packet_len;
|
||||
es->type = PES_PRIVATE1;
|
||||
es->payload_size -= packet_len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -1582,7 +1621,7 @@ static int fill_packet(demuxer_t *demuxer, demux_stream_t *ds, demux_packet_t **
|
||||
resize_demux_packet(*dp, ret); //shrinked to the right size
|
||||
ds_add_packet(ds, *dp);
|
||||
mp_msg(MSGT_DEMUX, MSGL_DBG2, "ADDED %d bytes to %s fifo, PTS=%f\n", ret, (ds == demuxer->audio ? "audio" : (ds == demuxer->video ? "video" : "sub")), (*dp)->pts);
|
||||
}
|
||||
}
|
||||
|
||||
*dp = NULL;
|
||||
*dp_offset = 0;
|
||||
@ -1630,7 +1669,7 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
|
||||
|
||||
if(! ts_sync(stream))
|
||||
{
|
||||
mp_msg(MSGT_DEMUX, MSGL_DBG2, "TS_PARSE: COULDN'T SYNC\n");
|
||||
mp_msg(MSGT_DEMUX, MSGL_INFO, "TS_PARSE: COULDN'T SYNC\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1754,7 +1793,8 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
|
||||
priv->last_pid = pid;
|
||||
|
||||
is_video = ((tss->type == VIDEO_MPEG1) || (tss->type == VIDEO_MPEG2) || (tss->type == VIDEO_MPEG4));
|
||||
is_audio = ((tss->type == AUDIO_MP2) || (tss->type == AUDIO_A52) || (tss->type == AUDIO_LPCM_BE) || (tss->type == AUDIO_AAC));
|
||||
is_audio = ((tss->type == AUDIO_MP2) || (tss->type == AUDIO_A52) || (tss->type == AUDIO_LPCM_BE) || (tss->type == AUDIO_AAC)
|
||||
|| (tss->type == PES_PRIVATE1));
|
||||
is_sub = ((tss->type == SPU_DVD) || (tss->type == SPU_DVB));
|
||||
pid_type = pid_type_from_pmt(priv, pid);
|
||||
|
||||
@ -1872,15 +1912,41 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
|
||||
stream_read(stream, p, buf_size);
|
||||
|
||||
len = pes_parse2(p, buf_size, es, pid_type);
|
||||
|
||||
if(len > 0)
|
||||
es->pid = tss->pid;
|
||||
|
||||
if(probe)
|
||||
{
|
||||
if(es->type == UNKNOWN)
|
||||
continue;
|
||||
|
||||
es->pid = tss->pid;
|
||||
tss->type = es->type;
|
||||
|
||||
return 0;
|
||||
if(len == 0)
|
||||
{
|
||||
if(tss->type != UNKNOWN)
|
||||
{
|
||||
es->size = buf_size;
|
||||
es->start = p;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tss->type = es->type;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(len == 0)
|
||||
{
|
||||
if(tss->type != UNKNOWN)
|
||||
{
|
||||
len = es->size = buf_size; //push the whole packet to the fifo
|
||||
//(we already learned what it is during the probe phase)
|
||||
es->start = p;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if((es->pts < tss->last_pts) && es->pts)
|
||||
mp_msg(MSGT_DEMUX, MSGL_DBG2, "BACKWARDS PTS! : NEW: %f -> LAST: %f, PID %d\n", es->pts, tss->last_pts, tss->pid);
|
||||
|
||||
@ -1896,12 +1962,6 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
|
||||
|
||||
demuxer->filepos = stream_tell(demuxer->stream) - es->size;
|
||||
|
||||
if(probe)
|
||||
return 1; //es->size;
|
||||
else
|
||||
{
|
||||
if(es->size > 0)
|
||||
{
|
||||
if(*dp_offset + es->size > *buffer_size)
|
||||
{
|
||||
*buffer_size = *dp_offset + es->size + TS_FEC_PACKET_SIZE;
|
||||
@ -1914,22 +1974,18 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
|
||||
(*dp)->flags = 0;
|
||||
(*dp)->pos = stream_tell(demuxer->stream);
|
||||
(*dp)->pts = es->pts;
|
||||
}
|
||||
|
||||
if(retv > 0)
|
||||
return retv;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if(is_audio)
|
||||
{
|
||||
retv = fill_packet(demuxer, ds, dp, dp_offset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(retv > 0)
|
||||
return retv;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1938,7 +1994,10 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
|
||||
if(tss->type == UNKNOWN)
|
||||
{
|
||||
stream_skip(stream, buf_size);
|
||||
continue;
|
||||
if(probe)
|
||||
return 0;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -1989,6 +2048,7 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
|
||||
|
||||
if(is_audio)
|
||||
{
|
||||
(*dp)->pts = tss->last_pts;
|
||||
retv = fill_packet(demuxer, ds, dp, dp_offset);
|
||||
return 1;
|
||||
}
|
||||
@ -1998,7 +2058,7 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
|
||||
else
|
||||
{
|
||||
stream_read(stream, es->start, sz);
|
||||
if(buf_size - sz) stream_read(stream, tmp, buf_size-sz);
|
||||
if(buf_size - sz) stream_skip(stream, buf_size-sz);
|
||||
|
||||
if(es->size)
|
||||
return es->size;
|
||||
|
Loading…
Reference in New Issue
Block a user