1
0
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:
nicodvb 2004-06-18 20:02:05 +00:00
parent 00a4249b4a
commit 89f39f93e4

View File

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