Mercurial > mplayer.hg
annotate libmpdemux/parse_mp4.c @ 36537:3b2228019b6a
vo_bl: update copyright header.
Patch by Stefan Schuermans [stefan blinkenarea org].
author | reimar |
---|---|
date | Sun, 19 Jan 2014 12:06:04 +0000 |
parents | 32725ca88fed |
children |
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 |
30570
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
29263
diff
changeset
|
36 static int mp4_read_descr_len(stream_t *s) |
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
29263
diff
changeset
|
37 { |
5301 | 38 uint8_t b; |
39 uint8_t numBytes = 0; | |
40 uint32_t length = 0; | |
41 | |
42 do { | |
43 b = stream_read_char(s); | |
44 numBytes++; | |
45 length = (length << 7) | (b & 0x7F); | |
46 } while ((b & 0x80) && numBytes < 4); | |
47 | |
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
|
48 //printf("MP4 read desc len: %d\n", length); |
5301 | 49 return length; |
50 } | |
51 | |
5305 | 52 /* parse the data part of MP4 esds atoms */ |
5301 | 53 int mp4_parse_esds(unsigned char *data, int datalen, esds_t *esds) { |
54 /* create memory stream from data */ | |
55 stream_t *s = new_memory_stream(data, datalen); | |
18666 | 56 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
|
57 #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
|
58 {int i; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29087
diff
changeset
|
59 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
|
60 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
|
61 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
|
62 printf("\nESDS Dumped\n");} |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29087
diff
changeset
|
63 #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
|
64 memset(esds, 0, sizeof(esds_t)); |
5301 | 65 |
66 esds->version = stream_read_char(s); | |
67 esds->flags = stream_read_int24(s); | |
68 mp_msg(MSGT_DEMUX, MP4_DL, | |
69 "ESDS MPEG4 version: %d flags: 0x%06X\n", | |
70 esds->version, esds->flags); | |
71 | |
72 /* get and verify ES_DescrTag */ | |
5305 | 73 if (stream_read_char(s) == MP4ESDescrTag) { |
5301 | 74 /* 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
|
75 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
|
76 |
5301 | 77 esds->ESId = stream_read_word(s); |
78 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
|
79 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
|
80 "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
|
81 " -> 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
|
82 " -> 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
|
83 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
|
84 |
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 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
|
86 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
|
87 } |
5301 | 88 } else { |
89 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
|
90 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
|
91 "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
|
92 " -> ESId: %d\n", 2, esds->ESId); |
5301 | 93 } |
94 | |
95 /* get and verify DecoderConfigDescrTab */ | |
96 if (stream_read_char(s) != MP4DecConfigDescrTag) { | |
5303 | 97 freereturn(s,1); |
5301 | 98 } |
99 | |
100 /* 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
|
101 len = mp4_read_descr_len(s); |
5301 | 102 |
103 esds->objectTypeId = stream_read_char(s); | |
104 esds->streamType = stream_read_char(s); | |
105 esds->bufferSizeDB = stream_read_int24(s); | |
106 esds->maxBitrate = stream_read_dword(s); | |
107 esds->avgBitrate = stream_read_dword(s); | |
108 mp_msg(MSGT_DEMUX, MP4_DL, | |
109 "ESDS MPEG4 Decoder Config Descriptor (%dBytes):\n" | |
110 " -> objectTypeId: %d\n" | |
111 " -> streamType: 0x%02X\n" | |
112 " -> bufferSizeDB: 0x%06X\n" | |
113 " -> maxBitrate: %.3fkbit/s\n" | |
114 " -> avgBitrate: %.3fkbit/s\n", | |
115 len, esds->objectTypeId, esds->streamType, | |
116 esds->bufferSizeDB, esds->maxBitrate/1000.0, | |
117 esds->avgBitrate/1000.0); | |
118 | |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
119 esds->decoderConfigLen=0; |
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
120 |
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
|
121 if (len < 15) { |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
122 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
|
123 } |
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
|
124 |
5301 | 125 /* get and verify DecSpecificInfoTag */ |
126 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
|
127 freereturn(s,0); |
5301 | 128 } |
129 | |
130 /* read length */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29087
diff
changeset
|
131 esds->decoderConfigLen = len = mp4_read_descr_len(s); |
5301 | 132 |
133 esds->decoderConfig = malloc(esds->decoderConfigLen); | |
134 if (esds->decoderConfig) { | |
135 stream_read(s, esds->decoderConfig, esds->decoderConfigLen); | |
136 } else { | |
137 esds->decoderConfigLen = 0; | |
138 } | |
139 mp_msg(MSGT_DEMUX, MP4_DL, | |
140 "ESDS MPEG4 Decoder Specific Descriptor (%dBytes)\n", len); | |
141 | |
5305 | 142 /* get and verify SLConfigDescrTag */ |
143 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
|
144 freereturn(s,0); |
5305 | 145 } |
146 | |
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
|
147 /* Note: SLConfig is usually constant value 2, size 1Byte */ |
5333 | 148 esds->SLConfigLen = len = mp4_read_descr_len(s); |
5305 | 149 esds->SLConfig = malloc(esds->SLConfigLen); |
150 if (esds->SLConfig) { | |
151 stream_read(s, esds->SLConfig, esds->SLConfigLen); | |
152 } else { | |
153 esds->SLConfigLen = 0; | |
154 } | |
155 mp_msg(MSGT_DEMUX, MP4_DL, | |
156 "ESDS MPEG4 Sync Layer Config Descriptor (%dBytes)\n" | |
157 " -> predefined: %d\n", len, esds->SLConfig[0]); | |
158 | |
5301 | 159 /* will skip the remainder of the atom */ |
5303 | 160 freereturn(s,0); |
5301 | 161 |
162 } | |
163 | |
5305 | 164 /* cleanup all mem occupied by mp4_parse_esds */ |
165 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
|
166 if(esds->decoderConfigLen) |
5305 | 167 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
|
168 if(esds->SLConfigLen) |
5305 | 169 free(esds->SLConfig); |
170 } | |
171 | |
5303 | 172 #undef freereturn |
173 #undef MP4_DL |