summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmpdemux/demux_mov.c16
-rw-r--r--libmpdemux/parse_mp4.c34
-rw-r--r--libmpdemux/parse_mp4.h1
3 files changed, 38 insertions, 13 deletions
diff --git a/libmpdemux/demux_mov.c b/libmpdemux/demux_mov.c
index 9b3e3278fb..dd4be1daea 100644
--- a/libmpdemux/demux_mov.c
+++ b/libmpdemux/demux_mov.c
@@ -706,21 +706,17 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
case MOV_FOURCC('e','s','d','s'): {
mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found MPEG4 audio Elementary Stream Descriptor atom (%d)!\n", atom_len);
if(atom_len >= 8) {
- esds_t *esds = (esds_t *)malloc(sizeof(esds_t));
- if(esds && !mp4_parse_esds(&trak->stdata[36], atom_len-8, esds)) {
+ esds_t esds;
+ if(!mp4_parse_esds(&trak->stdata[36], atom_len-8, &esds)) {
- sh->i_bps = esds->avgBitrate/8;
+ sh->i_bps = esds.avgBitrate/8;
// dump away the codec specific configuration for the AAC decoder
- sh->codecdata_len = esds->decoderConfigLen;
+ sh->codecdata_len = esds.decoderConfigLen;
sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);
- memcpy(sh->codecdata, esds->decoderConfig, sh->codecdata_len);
- }
- if(esds) {
- if(esds->decoderConfig)
- free(esds->decoderConfig);
- free(esds);
+ memcpy(sh->codecdata, esds.decoderConfig, sh->codecdata_len);
}
+ mp4_free_esds(&esds); // freeup esds mem
#if 0
{ FILE* f=fopen("esds.dat","wb");
fwrite(&trak->stdata[36],atom_len-8,1,f);
diff --git a/libmpdemux/parse_mp4.c b/libmpdemux/parse_mp4.c
index 512496984c..8ffc70d53f 100644
--- a/libmpdemux/parse_mp4.c
+++ b/libmpdemux/parse_mp4.c
@@ -29,10 +29,10 @@ int mp4_read_descr_len(stream_t *s) {
return length;
}
+/* parse the data part of MP4 esds atoms */
int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds) {
/* create memory stream from data */
stream_t *s = new_memory_stream(data, datalen);
- uint8_t tag;
uint8_t len;
esds->version = stream_read_char(s);
@@ -42,8 +42,7 @@ int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds) {
esds->version, esds->flags);
/* get and verify ES_DescrTag */
- tag = stream_read_char(s);
- if (tag == MP4ESDescrTag) {
+ if (stream_read_char(s) == MP4ESDescrTag) {
/* read length */
if ((len = mp4_read_descr_len(s)) < 5 + 15) {
freereturn(s,1);
@@ -107,11 +106,40 @@ int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds) {
mp_msg(MSGT_DEMUX, MP4_DL,
"ESDS MPEG4 Decoder Specific Descriptor (%dBytes)\n", len);
+ /* get and verify SLConfigDescrTag */
+ if(stream_read_char(s) != MP4SLConfigDescrTag) {
+ freereturn(s,1);
+ }
+
+ if((len = mp4_read_descr_len(s)) < 1) {
+ freereturn(s,1);
+ }
+
+ /* Note: SLConfig is usually constant value 2 size 1Byte */
+ esds->SLConfigLen = len;
+ esds->SLConfig = malloc(esds->SLConfigLen);
+ if (esds->SLConfig) {
+ stream_read(s, esds->SLConfig, esds->SLConfigLen);
+ } else {
+ esds->SLConfigLen = 0;
+ }
+ mp_msg(MSGT_DEMUX, MP4_DL,
+ "ESDS MPEG4 Sync Layer Config Descriptor (%dBytes)\n"
+ " -> predefined: %d\n", len, esds->SLConfig[0]);
+
/* will skip the remainder of the atom */
freereturn(s,0);
}
+/* cleanup all mem occupied by mp4_parse_esds */
+void mp4_free_esds(esds_t *esds) {
+ if(esds->decoderConfig)
+ free(esds->decoderConfig);
+ if(esds->SLConfig)
+ free(esds->SLConfig);
+}
+
#undef freereturn
#undef MP4_DL
diff --git a/libmpdemux/parse_mp4.h b/libmpdemux/parse_mp4.h
index 882924bfe0..01595a6946 100644
--- a/libmpdemux/parse_mp4.h
+++ b/libmpdemux/parse_mp4.h
@@ -73,6 +73,7 @@ typedef struct {
} esds_t;
int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds);
+void mp4_free_esds(esds_t *esds);
#endif /* !__PARSE_MP4_H */