Mercurial > mplayer.hg
annotate libmpdemux/parse_mp4.c @ 28706:3306a80b516b
Refactor code for upcoming alpha patches.
Patch by C¸«±dric Schieli, cschieli A gmail
author | cehoyos |
---|---|
date | Fri, 27 Feb 2009 20:44:59 +0000 |
parents | df67d03dde3b |
children | 88512570a249 |
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> | |
28594
df67d03dde3b
Convert HAVE_MALLOC_H into a 0/1 definition, fixes the warning:
diego
parents:
28110
diff
changeset
|
26 #if HAVE_MALLOC_H |
5301 | 27 #include <malloc.h> |
5403 | 28 #endif |
5404 | 29 #include <stdlib.h> |
5301 | 30 #include "parse_mp4.h" |
31 #include "mp_msg.h" | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
18666
diff
changeset
|
32 #include "stream/stream.h" |
5301 | 33 |
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
|
34 //#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
|
35 |
5301 | 36 #define MP4_DL MSGL_V |
5303 | 37 #define freereturn(a,b) free(a); return b |
5301 | 38 |
39 int mp4_read_descr_len(stream_t *s) { | |
40 uint8_t b; | |
41 uint8_t numBytes = 0; | |
42 uint32_t length = 0; | |
43 | |
44 do { | |
45 b = stream_read_char(s); | |
46 numBytes++; | |
47 length = (length << 7) | (b & 0x7F); | |
48 } while ((b & 0x80) && numBytes < 4); | |
49 | |
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
|
50 //printf("MP4 read desc len: %d\n", length); |
5301 | 51 return length; |
52 } | |
53 | |
5305 | 54 /* parse the data part of MP4 esds atoms */ |
5301 | 55 int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds) { |
56 /* create memory stream from data */ | |
57 stream_t *s = new_memory_stream(data, datalen); | |
18666 | 58 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
|
59 #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
|
60 {int 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("ESDS Dump (%dbyte):\n", datalen); |
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
|
62 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
|
63 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
|
64 printf("\nESDS Dumped\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
|
65 #endif |
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
|
66 memset(esds, 0, sizeof(esds_t)); |
5301 | 67 |
68 esds->version = stream_read_char(s); | |
69 esds->flags = stream_read_int24(s); | |
70 mp_msg(MSGT_DEMUX, MP4_DL, | |
71 "ESDS MPEG4 version: %d flags: 0x%06X\n", | |
72 esds->version, esds->flags); | |
73 | |
74 /* get and verify ES_DescrTag */ | |
5305 | 75 if (stream_read_char(s) == MP4ESDescrTag) { |
5301 | 76 /* 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
|
77 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
|
78 |
5301 | 79 esds->ESId = stream_read_word(s); |
80 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
|
81 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
|
82 "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
|
83 " -> 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
|
84 " -> 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
|
85 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
|
86 |
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
|
87 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
|
88 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
|
89 } |
5301 | 90 } else { |
91 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
|
92 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
|
93 "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
|
94 " -> ESId: %d\n", 2, esds->ESId); |
5301 | 95 } |
96 | |
97 /* get and verify DecoderConfigDescrTab */ | |
98 if (stream_read_char(s) != MP4DecConfigDescrTag) { | |
5303 | 99 freereturn(s,1); |
5301 | 100 } |
101 | |
102 /* 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
|
103 len = mp4_read_descr_len(s); |
5301 | 104 |
105 esds->objectTypeId = stream_read_char(s); | |
106 esds->streamType = stream_read_char(s); | |
107 esds->bufferSizeDB = stream_read_int24(s); | |
108 esds->maxBitrate = stream_read_dword(s); | |
109 esds->avgBitrate = stream_read_dword(s); | |
110 mp_msg(MSGT_DEMUX, MP4_DL, | |
111 "ESDS MPEG4 Decoder Config Descriptor (%dBytes):\n" | |
112 " -> objectTypeId: %d\n" | |
113 " -> streamType: 0x%02X\n" | |
114 " -> bufferSizeDB: 0x%06X\n" | |
115 " -> maxBitrate: %.3fkbit/s\n" | |
116 " -> avgBitrate: %.3fkbit/s\n", | |
117 len, esds->objectTypeId, esds->streamType, | |
118 esds->bufferSizeDB, esds->maxBitrate/1000.0, | |
119 esds->avgBitrate/1000.0); | |
120 | |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
121 esds->decoderConfigLen=0; |
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
122 |
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
|
123 if (len < 15) { |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
124 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
|
125 } |
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
|
126 |
5301 | 127 /* get and verify DecSpecificInfoTag */ |
128 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
|
129 freereturn(s,0); |
5301 | 130 } |
131 | |
132 /* read length */ | |
133 esds->decoderConfigLen = len = mp4_read_descr_len(s); | |
134 | |
135 esds->decoderConfig = malloc(esds->decoderConfigLen); | |
136 if (esds->decoderConfig) { | |
137 stream_read(s, esds->decoderConfig, esds->decoderConfigLen); | |
138 } else { | |
139 esds->decoderConfigLen = 0; | |
140 } | |
141 mp_msg(MSGT_DEMUX, MP4_DL, | |
142 "ESDS MPEG4 Decoder Specific Descriptor (%dBytes)\n", len); | |
143 | |
5305 | 144 /* get and verify SLConfigDescrTag */ |
145 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
|
146 freereturn(s,0); |
5305 | 147 } |
148 | |
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
|
149 /* Note: SLConfig is usually constant value 2, size 1Byte */ |
5333 | 150 esds->SLConfigLen = len = mp4_read_descr_len(s); |
5305 | 151 esds->SLConfig = malloc(esds->SLConfigLen); |
152 if (esds->SLConfig) { | |
153 stream_read(s, esds->SLConfig, esds->SLConfigLen); | |
154 } else { | |
155 esds->SLConfigLen = 0; | |
156 } | |
157 mp_msg(MSGT_DEMUX, MP4_DL, | |
158 "ESDS MPEG4 Sync Layer Config Descriptor (%dBytes)\n" | |
159 " -> predefined: %d\n", len, esds->SLConfig[0]); | |
160 | |
5301 | 161 /* will skip the remainder of the atom */ |
5303 | 162 freereturn(s,0); |
5301 | 163 |
164 } | |
165 | |
5305 | 166 /* cleanup all mem occupied by mp4_parse_esds */ |
167 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
|
168 if(esds->decoderConfigLen) |
5305 | 169 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
|
170 if(esds->SLConfigLen) |
5305 | 171 free(esds->SLConfig); |
172 } | |
173 | |
5303 | 174 #undef freereturn |
175 #undef MP4_DL | |
176 |