Mercurial > mplayer.hg
annotate libmpdemux/parse_mp4.c @ 29285:1230bcd21ac6
synced with r2769
author | ptt |
---|---|
date | Thu, 28 May 2009 15:39:02 +0000 |
parents | 0f1b5b68af32 |
children | 98dc6ae7ede2 |
rev | line source |
---|---|
28106 | 1 /* |
2 * MP4 file format parser code | |
3 * | |
28110 | 4 * Copyright (C) 2002 Felix Buenemann <atmosfear at users.sourceforge.net> |
5301 | 5 * Code inspired by libmp4 from http://mpeg4ip.sourceforge.net/. |
28106 | 6 * |
7 * This file is part of MPlayer. | |
8 * | |
9 * MPlayer is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * MPlayer is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License along | |
20 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
5301 | 22 */ |
28106 | 23 |
5301 | 24 #include <stdio.h> |
25 #include <inttypes.h> | |
5404 | 26 #include <stdlib.h> |
5301 | 27 #include "parse_mp4.h" |
28 #include "mp_msg.h" | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
18666
diff
changeset
|
29 #include "stream/stream.h" |
5301 | 30 |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
31 //#define MP4_DUMPATOM |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
32 |
5301 | 33 #define MP4_DL MSGL_V |
5303 | 34 #define freereturn(a,b) free(a); return b |
5301 | 35 |
36 int mp4_read_descr_len(stream_t *s) { | |
37 uint8_t b; | |
38 uint8_t numBytes = 0; | |
39 uint32_t length = 0; | |
40 | |
41 do { | |
42 b = stream_read_char(s); | |
43 numBytes++; | |
44 length = (length << 7) | (b & 0x7F); | |
45 } while ((b & 0x80) && numBytes < 4); | |
46 | |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
47 //printf("MP4 read desc len: %d\n", length); |
5301 | 48 return length; |
49 } | |
50 | |
5305 | 51 /* parse the data part of MP4 esds atoms */ |
5301 | 52 int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds) { |
53 /* create memory stream from data */ | |
54 stream_t *s = new_memory_stream(data, datalen); | |
18666 | 55 uint16_t len; |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
56 #ifdef MP4_DUMPATOM |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
57 {int i; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29087
diff
changeset
|
58 printf("ESDS Dump (%dbyte):\n", datalen); |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
59 for(i = 0; i < datalen; i++) |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
60 printf("%02X ", data[i]); |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
61 printf("\nESDS Dumped\n");} |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29087
diff
changeset
|
62 #endif |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
63 memset(esds, 0, sizeof(esds_t)); |
5301 | 64 |
65 esds->version = stream_read_char(s); | |
66 esds->flags = stream_read_int24(s); | |
67 mp_msg(MSGT_DEMUX, MP4_DL, | |
68 "ESDS MPEG4 version: %d flags: 0x%06X\n", | |
69 esds->version, esds->flags); | |
70 | |
71 /* get and verify ES_DescrTag */ | |
5305 | 72 if (stream_read_char(s) == MP4ESDescrTag) { |
5301 | 73 /* read length */ |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
74 len = mp4_read_descr_len(s); |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
75 |
5301 | 76 esds->ESId = stream_read_word(s); |
77 esds->streamPriority = stream_read_char(s); | |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
78 mp_msg(MSGT_DEMUX, MP4_DL, |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
79 "ESDS MPEG4 ES Descriptor (%dBytes):\n" |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
80 " -> ESId: %d\n" |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
81 " -> streamPriority: %d\n", |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
82 len, esds->ESId, esds->streamPriority); |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
83 |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
84 if (len < (5 + 15)) { |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
85 freereturn(s,1); |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
86 } |
5301 | 87 } else { |
88 esds->ESId = stream_read_word(s); | |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
89 mp_msg(MSGT_DEMUX, MP4_DL, |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
90 "ESDS MPEG4 ES Descriptor (%dBytes):\n" |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
91 " -> ESId: %d\n", 2, esds->ESId); |
5301 | 92 } |
93 | |
94 /* get and verify DecoderConfigDescrTab */ | |
95 if (stream_read_char(s) != MP4DecConfigDescrTag) { | |
5303 | 96 freereturn(s,1); |
5301 | 97 } |
98 | |
99 /* read length */ | |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
100 len = mp4_read_descr_len(s); |
5301 | 101 |
102 esds->objectTypeId = stream_read_char(s); | |
103 esds->streamType = stream_read_char(s); | |
104 esds->bufferSizeDB = stream_read_int24(s); | |
105 esds->maxBitrate = stream_read_dword(s); | |
106 esds->avgBitrate = stream_read_dword(s); | |
107 mp_msg(MSGT_DEMUX, MP4_DL, | |
108 "ESDS MPEG4 Decoder Config Descriptor (%dBytes):\n" | |
109 " -> objectTypeId: %d\n" | |
110 " -> streamType: 0x%02X\n" | |
111 " -> bufferSizeDB: 0x%06X\n" | |
112 " -> maxBitrate: %.3fkbit/s\n" | |
113 " -> avgBitrate: %.3fkbit/s\n", | |
114 len, esds->objectTypeId, esds->streamType, | |
115 esds->bufferSizeDB, esds->maxBitrate/1000.0, | |
116 esds->avgBitrate/1000.0); | |
117 | |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
118 esds->decoderConfigLen=0; |
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
119 |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
120 if (len < 15) { |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
121 freereturn(s,0); |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
122 } |
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
123 |
5301 | 124 /* get and verify DecSpecificInfoTag */ |
125 if (stream_read_char(s) != MP4DecSpecificDescrTag) { | |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
126 freereturn(s,0); |
5301 | 127 } |
128 | |
129 /* read length */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29087
diff
changeset
|
130 esds->decoderConfigLen = len = mp4_read_descr_len(s); |
5301 | 131 |
132 esds->decoderConfig = malloc(esds->decoderConfigLen); | |
133 if (esds->decoderConfig) { | |
134 stream_read(s, esds->decoderConfig, esds->decoderConfigLen); | |
135 } else { | |
136 esds->decoderConfigLen = 0; | |
137 } | |
138 mp_msg(MSGT_DEMUX, MP4_DL, | |
139 "ESDS MPEG4 Decoder Specific Descriptor (%dBytes)\n", len); | |
140 | |
5305 | 141 /* get and verify SLConfigDescrTag */ |
142 if(stream_read_char(s) != MP4SLConfigDescrTag) { | |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
143 freereturn(s,0); |
5305 | 144 } |
145 | |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
146 /* Note: SLConfig is usually constant value 2, size 1Byte */ |
5333 | 147 esds->SLConfigLen = len = mp4_read_descr_len(s); |
5305 | 148 esds->SLConfig = malloc(esds->SLConfigLen); |
149 if (esds->SLConfig) { | |
150 stream_read(s, esds->SLConfig, esds->SLConfigLen); | |
151 } else { | |
152 esds->SLConfigLen = 0; | |
153 } | |
154 mp_msg(MSGT_DEMUX, MP4_DL, | |
155 "ESDS MPEG4 Sync Layer Config Descriptor (%dBytes)\n" | |
156 " -> predefined: %d\n", len, esds->SLConfig[0]); | |
157 | |
5301 | 158 /* will skip the remainder of the atom */ |
5303 | 159 freereturn(s,0); |
5301 | 160 |
161 } | |
162 | |
5305 | 163 /* cleanup all mem occupied by mp4_parse_esds */ |
164 void mp4_free_esds(esds_t *esds) { | |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
165 if(esds->decoderConfigLen) |
5305 | 166 free(esds->decoderConfig); |
5332
a3874da21700
Fix some silly logical bugs and fix memory cleanup in case mp4_parse_es returned with an error by memsetting the esds struct to 0 on init.
atmos4
parents:
5305
diff
changeset
|
167 if(esds->SLConfigLen) |
5305 | 168 free(esds->SLConfig); |
169 } | |
170 | |
5303 | 171 #undef freereturn |
172 #undef MP4_DL | |
173 |