[MPlayer-cvslog] CVS: main/libmpdemux demux_ts.c,1.29,1.30
Nico Sabbi CVS
syncmail at mplayerhq.hu
Sun Apr 3 13:47:23 CEST 2005
CVS change done by Nico Sabbi CVS
Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var2/tmp/cvs-serv587
Modified Files:
demux_ts.c
Log Message:
allocate and fill extradata field for video_avc (raw nal units, extradata contains sps+pps); fixed payload_size assignment for SL payloads
Index: demux_ts.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_ts.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- demux_ts.c 23 Mar 2005 07:53:37 -0000 1.29
+++ demux_ts.c 3 Apr 2005 11:47:20 -0000 1.30
@@ -36,6 +36,7 @@
#include "bswap.h"
#include "../unrarlib.h"
+#include "ms_hdr.h"
#define TS_PH_PACKET_SIZE 192
#define TS_FEC_PACKET_SIZE 204
@@ -63,6 +64,7 @@
VIDEO_MPEG2 = 0x10000002,
VIDEO_MPEG4 = 0x10000004,
VIDEO_H264 = 0x10000005,
+ VIDEO_AVC = mmioFOURCC('a', 'v', 'c', '1'),
AUDIO_MP2 = 0x50,
AUDIO_A52 = 0x2000,
AUDIO_LPCM_BE = 0x10001,
@@ -91,6 +93,8 @@
int last_cc; // last cc code (-1 if first packet)
int is_synced;
ts_section_t section;
+ uint8_t *extradata;
+ int extradata_alloc, extradata_len;
struct {
uint8_t au_start, au_end, last_au_end;
} sl;
@@ -112,6 +116,9 @@
typedef struct {
int32_t object_type; //aka codec used
int32_t stream_type; //video, audio etc.
+ uint8_t buf[4096];
+ uint16_t buf_size;
+ uint8_t szm1;
} mp4_decoder_config_t;
typedef struct {
@@ -211,7 +218,7 @@
#define IS_AUDIO(x) (((x) == AUDIO_MP2) || ((x) == AUDIO_A52) || ((x) == AUDIO_LPCM_BE) || ((x) == AUDIO_AAC))
-#define IS_VIDEO(x) (((x) == VIDEO_MPEG1) || ((x) == VIDEO_MPEG2) || ((x) == VIDEO_MPEG4) || ((x) == VIDEO_H264))
+#define IS_VIDEO(x) (((x) == VIDEO_MPEG1) || ((x) == VIDEO_MPEG2) || ((x) == VIDEO_MPEG4) || ((x) == VIDEO_H264) || ((x) == VIDEO_AVC))
static int ts_parse(demuxer_t *demuxer, ES_stream_t *es, unsigned char *packet, int probe);
extern void resync_audio_stream( sh_audio_t *sh_audio );
@@ -728,10 +735,20 @@
}
if(video_found)
- mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO %s(pid=%d)...", (param->vtype == VIDEO_MPEG1 ? "MPEG1" : (param->vtype == VIDEO_MPEG2 ? "MPEG2" : (param->vtype == VIDEO_MPEG4 ? "MPEG4" : "H264"))), param->vpid);
+ {
+ if(param->vtype == VIDEO_MPEG1)
+ mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG1(pid=%d)", param->vpid);
+ else if(param->vtype == VIDEO_MPEG2)
+ mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG2(pid=%d)", param->vpid);
+ else if(param->vtype == VIDEO_MPEG4)
+ mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG4(pid=%d)...", param->vpid);
+ else if(param->vtype == VIDEO_H264)
+ mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO H264(pid=%d)...", param->vpid);
+ else if(param->vtype == VIDEO_AVC)
+ mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO AVC(NAL-H264, pid=%d)...", param->vpid);
+ }
else
{
- video_found = 0;
param->vtype = UNKNOWN;
//WE DIDN'T MATCH ANY VIDEO STREAM
mp_msg(MSGT_DEMUXER, MSGL_INFO, "NO VIDEO! ");
@@ -871,7 +888,18 @@
if(params.vtype != UNKNOWN)
{
+ ES_stream_t *es = priv->ts.pids[params.vpid];
sh_video = new_sh_video(demuxer, 0);
+ if(params.vtype == VIDEO_AVC && es->extradata && es->extradata_len)
+ {
+ sh_video->bih = (BITMAPINFOHEADER *) calloc(1, sizeof(BITMAPINFOHEADER) + 4096);
+ sh_video->bih->biSize= sizeof(BITMAPINFOHEADER) + es->extradata_len;
+ memcpy(sh_video->bih + 1, es->extradata, es->extradata_len);
+ mp_msg(MSGT_DEMUXER,MSGL_DBG2, "EXTRADATA(%d BYTES): \n", es->extradata_len);
+ for(i = 0;i < es->extradata_len; i++)
+ mp_msg(MSGT_DEMUXER,MSGL_DBG2, "%02x ", (int) es->extradata[i]);
+ mp_msg(MSGT_DEMUXER,MSGL_DBG2,"\n");
+ }
sh_video->ds = demuxer->video;
sh_video->format = params.vtype;
demuxer->video->sh = sh_video;
@@ -950,31 +978,31 @@
extern unsigned char mp_getbits(unsigned char*, unsigned int, unsigned char);
#define getbits mp_getbits
-static int mp4_parse_sl_packet(pmt_t *pmt, uint8_t *buf, uint16_t packet_len, int pid, int is_aligned, ES_stream_t *pes_es)
+static int mp4_parse_sl_packet(pmt_t *pmt, uint8_t *buf, uint16_t packet_len, int pid, ES_stream_t *pes_es)
{
- int i, n, m, es_id = -1;
+ int i, n, m, mp4_es_id = -1;
uint64_t v = 0;
uint32_t pl_size = 0;
int deg_flag = 0;
mp4_es_descr_t *es = NULL;
mp4_sl_config_t *sl = NULL;
- uint8_t au_start = 0, au_end = 0, rap_flag = 0, ocr_flag = 0, random_accesspoint = 0, random_accesspoint_only = 0,
- padding = 0, padding_bits = 0, use_ts = 0, idle = 0, duration = 0;
+ uint8_t au_start = 0, au_end = 0, rap_flag = 0, ocr_flag = 0, padding = 0, padding_bits = 0, idle = 0;
- if(! pmt || ! is_aligned || !packet_len) //FIXME
+ mp_msg(MSGT_DEMUXER,MSGL_V, "mp4_parse_sl_packet, pid: %d, pmt: %pm, packet_len: %d\n", pid, pmt, packet_len);
+ if(! pmt || !packet_len)
return 0;
for(i = 0; i < pmt->es_cnt; i++)
{
if(pmt->es[i].pid == pid)
- es_id = pmt->es[i].mp4_es_id;
+ mp4_es_id = pmt->es[i].mp4_es_id;
}
- if(es_id < 0)
+ if(mp4_es_id < 0)
return -1;
for(i = 0; i < pmt->mp4es_cnt; i++)
{
- if(pmt->mp4es[i].id == es_id)
+ if(pmt->mp4es[i].id == mp4_es_id)
es = &(pmt->mp4es[i]);
}
if(! es)
@@ -987,7 +1015,7 @@
return -1;
//now es is the complete es_descriptor of out mp4 ES stream
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "ID: %d, FLAGS: 0x%x\n", es->id, sl->flags);
+ mp_msg(MSGT_DEMUXER,MSGL_DBG2, "ID: %d, FLAGS: 0x%x, subtype: %x\n", es->id, sl->flags, pes_es->subtype);
n = 0;
if(sl->au_start)
@@ -1025,7 +1053,7 @@
//(! idle && (!padding || padding_bits != 0)) is true
n += sl->packet_seqnum_len;
if(sl->degr_len)
- deg_flag = getbits(buf, n++, 3);
+ deg_flag = getbits(buf, n++, 1);
if(deg_flag)
n += sl->degr_len;
@@ -1042,7 +1070,6 @@
if(au_start)
{
int dts_flag = 0, cts_flag = 0, ib_flag = 0;
- uint64_t dts, cts;
if(sl->random_accesspoint)
rap_flag = getbits(buf, n++, 1);
@@ -1055,11 +1082,11 @@
return -1;
if(sl->use_ts)
{
- dts_flag = getbits(buf, n++, 3);
- cts_flag = getbits(buf, n++, 3);
+ dts_flag = getbits(buf, n++, 1);
+ cts_flag = getbits(buf, n++, 1);
}
if(sl->instant_bitrate_len)
- ib_flag = getbits(buf, n++, 3);
+ ib_flag = getbits(buf, n++, 1);
if(packet_len * 8 <= n+8)
return -1;
if(dts_flag && (sl->ts_len > 0))
@@ -1109,14 +1136,11 @@
}
m = (n+7)/8;
- pes_es->payload_size -= min(m, pes_es->payload_size);
if(0 < pl_size && pl_size < pes_es->payload_size)
pes_es->payload_size = pl_size;
- if(pes_es->sl.au_start && pes_es->payload_size)
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "4bytes of payload (%d bytes) %02x %02x %02x %02x \n", pes_es->payload_size, buf[m], buf[m+1], buf[m+2], buf[m+3]);
- mp_msg(MSGT_DEMUXER,MSGL_DBG2, "mp4_parse_sl_packet, final n=%d, m=%d, RAP_FLAG: %d, RAP_ALWAYS: %d, size from pes hdr: %u, size from sl hdr: %d\n",
- n, m, rap_flag, sl->random_accesspoint_only, pes_es->payload_size, pl_size);
+ mp_msg(MSGT_DEMUXER,MSGL_V, "mp4_parse_sl_packet, n=%d, m=%d, size from pes hdr: %u, sl hdr size: %u, RAP FLAGS: %d/%d\n",
+ n, m, pes_es->payload_size, pl_size, (int) rap_flag, (int) sl->random_accesspoint_only);
return m;
}
@@ -1188,11 +1212,6 @@
p += header_len + 9;
packet_len -= header_len + 3;
- /*
- if(packet_len <= 0)
- mp_msg(MSGT_DEMUX, MSGL_INFO, "\n\nNow: %d, prima: %d, ORIG: %d\n\n\n", packet_len, packet_len+3+header_len, pkt_len);
- */
-
if(es->payload_size)
es->payload_size -= header_len + 3;
@@ -1308,23 +1327,26 @@
es->start = p;
es->size = packet_len;
es->type = type_from_pmt;
- if(es->payload_size)
- es->payload_size -= es->size;
if(type_from_pmt == SL_PES_STREAM)
{
- l = mp4_parse_sl_packet(pmt, p, packet_len, pid, pes_is_aligned, es);
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "L=%d, TYPE=%x\n", l, type_from_pmt);
- if(l < 0)
- {
- mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: couldn't parse SL header, passing along full PES payload\n");
- l = 0;
- }
+ //if(pes_is_aligned)
+ //{
+ l = mp4_parse_sl_packet(pmt, p, packet_len, pid, es);
+ mp_msg(MSGT_DEMUX, MSGL_DBG2, "L=%d, TYPE=%x\n", l, type_from_pmt);
+ if(l < 0)
+ {
+ mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: couldn't parse SL header, passing along full PES payload\n");
+ l = 0;
+ }
+ //}
es->start += l;
es->size -= l;
}
+ if(es->payload_size)
+ es->payload_size -= packet_len;
return 1;
}
}
@@ -1614,7 +1636,6 @@
static uint16_t parse_mp4_slconfig_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem)
{
int i = 0;
- uint64_t tslen = 0;
mp4_es_descr_t *es;
mp4_sl_config_t *sl;
@@ -1639,7 +1660,7 @@
i += 4;
sl->ocr_resolution = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3];
i += 4;
- tslen = sl->ts_len = buf[i];
+ sl->ts_len = buf[i];
i++;
sl->ocr_len = buf[i];
i++;
@@ -1657,8 +1678,8 @@
else if(buf[0] == 1)
{
sl->flags = 0;
- tslen = sl->ts_resolution = 1000;
- tslen = sl->ts_len = 32;
+ sl->ts_resolution = 1000;
+ sl->ts_len = 32;
i++;
}
else if(buf[0] == 2)
@@ -1693,7 +1714,7 @@
else //no support for fixed durations atm
sl->timescale = sl->au_duration = sl->cts_duration = 0;
- mp_msg(MSGT_DEMUX, MSGL_V, "MP4SLCONFIG(0x%x), predef: %d, flags: %x, use_ts: %d, tslen: %d, timescale: %d, dts: %llu, cts: %llu\n",
+ mp_msg(MSGT_DEMUX, MSGL_V, "MP4SLCONFIG(len=0x%x), predef: %d, flags: %x, use_ts: %d, tslen: %d, timescale: %d, dts: %llu, cts: %llu\n",
len, buf[0], sl->flags, sl->use_ts, sl->ts_len, sl->timescale, (uint64_t) sl->dts, (uint64_t) sl->cts);
return len;
@@ -1733,7 +1754,9 @@
else if(dec->object_type == 0x20)
dec->object_type = VIDEO_MPEG4;
else if(dec->object_type == 0x21)
- dec->object_type = VIDEO_H264;
+ dec->object_type = VIDEO_AVC;
+ /*else if(dec->object_type == 0x22)
+ fprintf(stderr, "TYPE 0x22\n");*/
else dec->object_type = UNKNOWN;
}
else if(dec->stream_type == 5)
@@ -1748,19 +1771,46 @@
else
dec->object_type = dec->stream_type = UNKNOWN;
+ if(len > 13)
+ parse_mp4_descriptors(pmt, &buf[13], len-13, dec);
+
mp_msg(MSGT_DEMUX, MSGL_V, "MP4DECODER(0x%x), object_type: 0x%x, stream_type: 0x%x\n", len, dec->object_type, dec->stream_type);
return len;
}
+static uint16_t parse_mp4_decoder_specific_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem)
+{
+ int i;
+ mp4_decoder_config_t *dec;
+
+ mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DECODER_SPECIFIC_DESCRIPTOR(%d)\n", len);
+ dec = (mp4_decoder_config_t *) elem;
+ if(!dec)
+ {
+ mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n");
+ return len;
+ }
+
+ mp_msg(MSGT_DEMUX, MSGL_DBG2, "MP4 SPECIFIC INFO BYTES: \n");
+ for(i=0; i<len; i++)
+ mp_msg(MSGT_DEMUX, MSGL_DBG2, "%02x ", buf[i]);
+ mp_msg(MSGT_DEMUX, MSGL_DBG2, "\n");
+
+ memcpy(dec->buf, buf, len);
+ dec->buf_size = len;
+
+ return len;
+}
+
static uint16_t parse_mp4_es_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem)
{
int i = 0, j = 0, k, found;
uint8_t flag;
- mp4_es_descr_t es, *target_es, *tmp;
+ mp4_es_descr_t es, *target_es = NULL, *tmp;
mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4ES: len=%d\n", len);
-
+ memset(&es, 0, sizeof(mp4_es_descr_t));
while(i < len)
{
es.id = (buf[i] << 8) | buf[i+1];
@@ -1897,6 +1947,9 @@
case 0x4:
parse_mp4_decoder_config_descriptor(pmt, &buf[i], descr_len, elem);
break;
+ case 0x05:
+ parse_mp4_decoder_specific_descriptor(pmt, &buf[i], descr_len, elem);
+ break;
case 0x6:
parse_mp4_slconfig_descriptor(pmt, &buf[i], descr_len, elem);
break;
@@ -1922,6 +1975,8 @@
tss->type = UNKNOWN;
tss->subtype = UNKNOWN;
tss->is_synced = 0;
+ tss->extradata = NULL;
+ tss->extradata_alloc = tss->extradata_len = 0;
priv->ts.pids[pid] = tss;
return tss;
@@ -2255,9 +2310,9 @@
return 1;
}
-static pmt_t* pmt_of_pid(ts_priv_t *priv, int pid)
+static pmt_t* pmt_of_pid(ts_priv_t *priv, int pid, mp4_decoder_config_t **mp4_dec)
{
- int32_t i, j;
+ int32_t i, j, k;
if(priv->pmt)
{
@@ -2266,11 +2321,28 @@
if(priv->pmt[i].es && priv->pmt[i].es_cnt)
{
for(j = 0; j < priv->pmt[i].es_cnt; j++)
+ {
if(priv->pmt[i].es[j].pid == pid)
+ {
+ //search mp4_es_id
+ if(priv->pmt[i].es[j].mp4_es_id)
+ {
+ for(k = 0; k < priv->pmt[i].mp4es_cnt; k++)
+ {
+ //fprintf(stderr, "K=%d, ID: %x, MP4ESID:%x\n", k, priv->pmt[i].mp4es[k].id, priv->pmt[i].es[j].mp4_es_id);
+ if(priv->pmt[i].mp4es[k].id == priv->pmt[i].es[j].mp4_es_id)
+ {
+ *mp4_dec = &(priv->pmt[i].mp4es[k].decoder);
+ break;
+ }
+ }
+ }
+
return &(priv->pmt[i]);
+ }
+ }
}
}
-
}
return NULL;
@@ -2340,7 +2412,7 @@
ret = *dp_offset;
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);
+ mp_msg(MSGT_DEMUX, MSGL_DBG2, "ADDED %d bytes to %s fifo, PTS=%.3f\n", ret, (ds == demuxer->audio ? "audio" : (ds == demuxer->video ? "video" : "sub")), (*dp)->pts);
}
*dp = NULL;
@@ -2349,6 +2421,27 @@
return ret;
}
+static int fill_extradata(mp4_decoder_config_t * mp4_dec, ES_stream_t *tss)
+{
+ uint8_t *tmp;
+
+ mp_msg(MSGT_DEMUX, MSGL_DBG2, "MP4_dec: %p, pid: %d\n", mp4_dec, tss->pid);
+
+ if(mp4_dec->buf_size > tss->extradata_alloc)
+ {
+ tmp = (uint8_t *) realloc(tss->extradata, mp4_dec->buf_size);
+ if(!tmp)
+ return 0;
+ tss->extradata = tmp;
+ tss->extradata_alloc = mp4_dec->buf_size;
+ }
+ memcpy(tss->extradata, mp4_dec->buf, mp4_dec->buf_size);
+ tss->extradata_len = mp4_dec->buf_size;
+ mp_msg(MSGT_DEMUX, MSGL_V, "EXTRADATA: %p, alloc=%d, len=%d\n", tss->extradata, tss->extradata_alloc, tss->extradata_len);
+
+ return tss->extradata_len;
+}
+
// 0 = EOF or no stream found
// else = [-] number of bytes written to the packet
static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet, int probe)
@@ -2359,13 +2452,14 @@
int len, cc, cc_ok, afc, retv = 0, is_video, is_audio, is_sub;
ts_priv_t * priv = (ts_priv_t*) demuxer->priv;
stream_t *stream = demuxer->stream;
- char *p, tmp[TS_FEC_PACKET_SIZE];
+ char *p;
demux_stream_t *ds = NULL;
demux_packet_t **dp = NULL;
int *dp_offset = 0, *buffer_size = 0;
int32_t progid, pid_type, bad, ts_error;
int junk = 0, rap_flag = 0;
pmt_t *pmt;
+ mp4_decoder_config_t *mp4_dec;
while(! done)
@@ -2375,6 +2469,7 @@
dp = (demux_packet_t **) NULL;
dp_offset = buffer_size = NULL;
rap_flag = 0;
+ mp4_dec = NULL;
junk = priv->ts.packet_size - TS_PACKET_SIZE;
buf_size = priv->ts.packet_size - junk;
@@ -2472,7 +2567,10 @@
//find the program that the pid belongs to; if (it's the right one or -1) && pid_type==SL_SECTION
//call parse_sl_section()
- pmt = pmt_of_pid(priv, pid);
+ pmt = pmt_of_pid(priv, pid, &mp4_dec);
+ if(mp4_dec)
+ fill_extradata(mp4_dec, tss);
+
//TABLE PARSING
@@ -2493,7 +2591,7 @@
if(pmt->mp4es[k].decoder.object_type == MP4_OD && pmt->mp4es[k].decoder.stream_type == MP4_OD)
mp4_es_id = pmt->mp4es[k].id;
}
- mp_msg(MSGT_DEMUX, MSGL_V, "ESID: %d\n", mp4_es_id);
+ mp_msg(MSGT_DEMUX, MSGL_DBG2, "MP4ESID: %d\n", mp4_es_id);
for(k = 0; k < pmt->es_cnt; k++)
{
if(pmt->es[k].mp4_es_id == mp4_es_id)
@@ -2793,7 +2891,6 @@
resize_demux_packet(*dp, *buffer_size);
//we'll skip at least one RESIZE() in the next iteration of ts_parse()
mp_msg(MSGT_DEMUX, MSGL_DBG2, "RESIZE DP TO %d\n", *buffer_size);
- //mp_msg(MSGT_DEMUX, MSGL_INFO, "SECOND TYPE=%x, bytes=%d, afc=%d, psize=%d, tell=%llu\n", es->type, sz, afc, tss->payload_size, (uint64_t) stream_tell(demuxer->stream));
}
stream_read(stream, &((*dp)->buffer[*dp_offset]), sz);
More information about the MPlayer-cvslog
mailing list