Mercurial > mplayer.hg
comparison libmpdemux/parse_mp4.c @ 5301:d72c3169a343
Improved MP4 parsing (finally)
author | atmos4 |
---|---|
date | Sun, 24 Mar 2002 02:25:41 +0000 |
parents | |
children | 534f16f50c17 |
comparison
equal
deleted
inserted
replaced
5300:5d7bd47b46ef | 5301:d72c3169a343 |
---|---|
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/. | |
6 */ | |
7 | |
8 #include <stdio.h> | |
9 #include <inttypes.h> | |
10 #include <malloc.h> | |
11 #include "parse_mp4.h" | |
12 #include "mp_msg.h" | |
13 #include "stream.h" | |
14 | |
15 #define MP4_DL MSGL_V | |
16 | |
17 int mp4_read_descr_len(stream_t *s) { | |
18 uint8_t b; | |
19 uint8_t numBytes = 0; | |
20 uint32_t length = 0; | |
21 | |
22 do { | |
23 b = stream_read_char(s); | |
24 numBytes++; | |
25 length = (length << 7) | (b & 0x7F); | |
26 } while ((b & 0x80) && numBytes < 4); | |
27 | |
28 return length; | |
29 } | |
30 | |
31 int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds) { | |
32 /* create memory stream from data */ | |
33 stream_t *s = new_memory_stream(data, datalen); | |
34 uint8_t tag; | |
35 uint8_t len; | |
36 | |
37 esds->version = stream_read_char(s); | |
38 esds->flags = stream_read_int24(s); | |
39 mp_msg(MSGT_DEMUX, MP4_DL, | |
40 "ESDS MPEG4 version: %d flags: 0x%06X\n", | |
41 esds->version, esds->flags); | |
42 | |
43 /* get and verify ES_DescrTag */ | |
44 tag = stream_read_char(s); | |
45 if (tag == MP4ESDescrTag) { | |
46 /* read length */ | |
47 if ((len = mp4_read_descr_len(s)) < 5 + 15) { | |
48 return 1; | |
49 } | |
50 esds->ESId = stream_read_word(s); | |
51 esds->streamPriority = stream_read_char(s); | |
52 } else { | |
53 #if 1 /* 1 == guessed */ | |
54 esds->ESId = stream_read_word(s); | |
55 #else | |
56 /* skip 2 bytes */ | |
57 stream_skip(s, 2); | |
58 #endif | |
59 } | |
60 mp_msg(MSGT_DEMUX, MP4_DL, | |
61 "ESDS MPEG4 ES Descriptor (%dBytes):\n" | |
62 " -> ESId: %d\n" | |
63 " -> streamPriority: %d\n", | |
64 len, esds->ESId, esds->streamPriority); | |
65 | |
66 /* get and verify DecoderConfigDescrTab */ | |
67 if (stream_read_char(s) != MP4DecConfigDescrTag) { | |
68 return 1; | |
69 } | |
70 | |
71 /* read length */ | |
72 if ((len = mp4_read_descr_len(s)) < 15) { | |
73 return 1; | |
74 } | |
75 | |
76 esds->objectTypeId = stream_read_char(s); | |
77 esds->streamType = stream_read_char(s); | |
78 esds->bufferSizeDB = stream_read_int24(s); | |
79 esds->maxBitrate = stream_read_dword(s); | |
80 esds->avgBitrate = stream_read_dword(s); | |
81 mp_msg(MSGT_DEMUX, MP4_DL, | |
82 "ESDS MPEG4 Decoder Config Descriptor (%dBytes):\n" | |
83 " -> objectTypeId: %d\n" | |
84 " -> streamType: 0x%02X\n" | |
85 " -> bufferSizeDB: 0x%06X\n" | |
86 " -> maxBitrate: %.3fkbit/s\n" | |
87 " -> avgBitrate: %.3fkbit/s\n", | |
88 len, esds->objectTypeId, esds->streamType, | |
89 esds->bufferSizeDB, esds->maxBitrate/1000.0, | |
90 esds->avgBitrate/1000.0); | |
91 | |
92 /* get and verify DecSpecificInfoTag */ | |
93 if (stream_read_char(s) != MP4DecSpecificDescrTag) { | |
94 return 1; | |
95 } | |
96 | |
97 /* read length */ | |
98 esds->decoderConfigLen = len = mp4_read_descr_len(s); | |
99 | |
100 free(esds->decoderConfig); | |
101 esds->decoderConfig = malloc(esds->decoderConfigLen); | |
102 if (esds->decoderConfig) { | |
103 stream_read(s, esds->decoderConfig, esds->decoderConfigLen); | |
104 } else { | |
105 esds->decoderConfigLen = 0; | |
106 } | |
107 mp_msg(MSGT_DEMUX, MP4_DL, | |
108 "ESDS MPEG4 Decoder Specific Descriptor (%dBytes)\n", len); | |
109 | |
110 /* will skip the remainder of the atom */ | |
111 return 0; | |
112 | |
113 } | |
114 |