1 /* parse_mp4.c - MP4 file format parser code
2 * This file is part of MPlayer, see http://mplayerhq.hu/ for info.
3 * (c)2002 by Felix Buenemann <atmosfear at users.sourceforge.net>
4 * File licensed under the GPL, see http://www.fsf.org/ for more info.
5 * Code inspired by libmp4 from http://mpeg4ip.sourceforge.net/.
14 #include "parse_mp4.h"
16 #include "stream/stream.h"
18 //#define MP4_DUMPATOM
21 #define freereturn(a,b) free(a); return b
23 int mp4_read_descr_len(stream_t
*s
) {
29 b
= stream_read_char(s
);
31 length
= (length
<< 7) | (b
& 0x7F);
32 } while ((b
& 0x80) && numBytes
< 4);
34 //printf("MP4 read desc len: %d\n", length);
38 /* parse the data part of MP4 esds atoms */
39 int mp4_parse_esds(unsigned char *data
, int datalen
, esds_t
*esds
) {
40 /* create memory stream from data */
41 stream_t
*s
= new_memory_stream(data
, datalen
);
45 printf("ESDS Dump (%dbyte):\n", datalen
);
46 for(i
= 0; i
< datalen
; i
++)
47 printf("%02X ", data
[i
]);
48 printf("\nESDS Dumped\n");}
50 memset(esds
, 0, sizeof(esds_t
));
52 esds
->version
= stream_read_char(s
);
53 esds
->flags
= stream_read_int24(s
);
54 mp_msg(MSGT_DEMUX
, MP4_DL
,
55 "ESDS MPEG4 version: %d flags: 0x%06X\n",
56 esds
->version
, esds
->flags
);
58 /* get and verify ES_DescrTag */
59 if (stream_read_char(s
) == MP4ESDescrTag
) {
61 len
= mp4_read_descr_len(s
);
63 esds
->ESId
= stream_read_word(s
);
64 esds
->streamPriority
= stream_read_char(s
);
65 mp_msg(MSGT_DEMUX
, MP4_DL
,
66 "ESDS MPEG4 ES Descriptor (%dBytes):\n"
68 " -> streamPriority: %d\n",
69 len
, esds
->ESId
, esds
->streamPriority
);
75 esds
->ESId
= stream_read_word(s
);
76 mp_msg(MSGT_DEMUX
, MP4_DL
,
77 "ESDS MPEG4 ES Descriptor (%dBytes):\n"
78 " -> ESId: %d\n", 2, esds
->ESId
);
81 /* get and verify DecoderConfigDescrTab */
82 if (stream_read_char(s
) != MP4DecConfigDescrTag
) {
87 len
= mp4_read_descr_len(s
);
89 esds
->objectTypeId
= stream_read_char(s
);
90 esds
->streamType
= stream_read_char(s
);
91 esds
->bufferSizeDB
= stream_read_int24(s
);
92 esds
->maxBitrate
= stream_read_dword(s
);
93 esds
->avgBitrate
= stream_read_dword(s
);
94 mp_msg(MSGT_DEMUX
, MP4_DL
,
95 "ESDS MPEG4 Decoder Config Descriptor (%dBytes):\n"
96 " -> objectTypeId: %d\n"
97 " -> streamType: 0x%02X\n"
98 " -> bufferSizeDB: 0x%06X\n"
99 " -> maxBitrate: %.3fkbit/s\n"
100 " -> avgBitrate: %.3fkbit/s\n",
101 len
, esds
->objectTypeId
, esds
->streamType
,
102 esds
->bufferSizeDB
, esds
->maxBitrate
/1000.0,
103 esds
->avgBitrate
/1000.0);
105 esds
->decoderConfigLen
=0;
111 /* get and verify DecSpecificInfoTag */
112 if (stream_read_char(s
) != MP4DecSpecificDescrTag
) {
117 esds
->decoderConfigLen
= len
= mp4_read_descr_len(s
);
119 esds
->decoderConfig
= malloc(esds
->decoderConfigLen
);
120 if (esds
->decoderConfig
) {
121 stream_read(s
, esds
->decoderConfig
, esds
->decoderConfigLen
);
123 esds
->decoderConfigLen
= 0;
125 mp_msg(MSGT_DEMUX
, MP4_DL
,
126 "ESDS MPEG4 Decoder Specific Descriptor (%dBytes)\n", len
);
128 /* get and verify SLConfigDescrTag */
129 if(stream_read_char(s
) != MP4SLConfigDescrTag
) {
133 /* Note: SLConfig is usually constant value 2, size 1Byte */
134 esds
->SLConfigLen
= len
= mp4_read_descr_len(s
);
135 esds
->SLConfig
= malloc(esds
->SLConfigLen
);
136 if (esds
->SLConfig
) {
137 stream_read(s
, esds
->SLConfig
, esds
->SLConfigLen
);
139 esds
->SLConfigLen
= 0;
141 mp_msg(MSGT_DEMUX
, MP4_DL
,
142 "ESDS MPEG4 Sync Layer Config Descriptor (%dBytes)\n"
143 " -> predefined: %d\n", len
, esds
->SLConfig
[0]);
145 /* will skip the remainder of the atom */
150 /* cleanup all mem occupied by mp4_parse_esds */
151 void mp4_free_esds(esds_t
*esds
) {
152 if(esds
->decoderConfigLen
)
153 free(esds
->decoderConfig
);
154 if(esds
->SLConfigLen
)
155 free(esds
->SLConfig
);