Mercurial > mplayer.hg
annotate libmpdemux/parse_mp4.c @ 16184:04dd5945fab8
100l to whoever wrote this crap using 1/10000 units. it caused framerates to get trashed from 30000/1001 to 2997/100, etc.!
author | rfelker |
---|---|
date | Sat, 06 Aug 2005 16:15:07 +0000 |
parents | a3aac765967d |
children | 492c6d674c3e |
rev | line source |
---|---|
5301 | 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> | |
5403 | 10 #ifdef HAVE_MALLOC_H |
5301 | 11 #include <malloc.h> |
5403 | 12 #endif |
5404 | 13 #include <stdlib.h> |
5301 | 14 #include "parse_mp4.h" |
15 #include "mp_msg.h" | |
16 #include "stream.h" | |
17 | |
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
|
18 //#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
|
19 |
5301 | 20 #define MP4_DL MSGL_V |
5303 | 21 #define freereturn(a,b) free(a); return b |
5301 | 22 |
23 int mp4_read_descr_len(stream_t *s) { | |
24 uint8_t b; | |
25 uint8_t numBytes = 0; | |
26 uint32_t length = 0; | |
27 | |
28 do { | |
29 b = stream_read_char(s); | |
30 numBytes++; | |
31 length = (length << 7) | (b & 0x7F); | |
32 } while ((b & 0x80) && numBytes < 4); | |
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 //printf("MP4 read desc len: %d\n", length); |
5301 | 35 return length; |
36 } | |
37 | |
5305 | 38 /* parse the data part of MP4 esds atoms */ |
5301 | 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); | |
42 uint8_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
|
43 #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
|
44 {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
|
45 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
|
46 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
|
47 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
|
48 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
|
49 #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
|
50 memset(esds, 0, sizeof(esds_t)); |
5301 | 51 |
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); | |
57 | |
58 /* get and verify ES_DescrTag */ | |
5305 | 59 if (stream_read_char(s) == MP4ESDescrTag) { |
5301 | 60 /* 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
|
61 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
|
62 |
5301 | 63 esds->ESId = stream_read_word(s); |
64 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
|
65 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
|
66 "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
|
67 " -> 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
|
68 " -> 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
|
69 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
|
70 |
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
|
71 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
|
72 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
|
73 } |
5301 | 74 } else { |
75 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
|
76 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
|
77 "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
|
78 " -> ESId: %d\n", 2, esds->ESId); |
5301 | 79 } |
80 | |
81 /* get and verify DecoderConfigDescrTab */ | |
82 if (stream_read_char(s) != MP4DecConfigDescrTag) { | |
5303 | 83 freereturn(s,1); |
5301 | 84 } |
85 | |
86 /* 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
|
87 len = mp4_read_descr_len(s); |
5301 | 88 |
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); | |
104 | |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
105 esds->decoderConfigLen=0; |
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
106 |
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
|
107 if (len < 15) { |
6929
a3aac765967d
allow early exit from esds parsing, so decoder info (type & bitrate) are
arpi
parents:
5404
diff
changeset
|
108 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
|
109 } |
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
|
110 |
5301 | 111 /* get and verify DecSpecificInfoTag */ |
112 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
|
113 freereturn(s,0); |
5301 | 114 } |
115 | |
116 /* read length */ | |
117 esds->decoderConfigLen = len = mp4_read_descr_len(s); | |
118 | |
119 esds->decoderConfig = malloc(esds->decoderConfigLen); | |
120 if (esds->decoderConfig) { | |
121 stream_read(s, esds->decoderConfig, esds->decoderConfigLen); | |
122 } else { | |
123 esds->decoderConfigLen = 0; | |
124 } | |
125 mp_msg(MSGT_DEMUX, MP4_DL, | |
126 "ESDS MPEG4 Decoder Specific Descriptor (%dBytes)\n", len); | |
127 | |
5305 | 128 /* get and verify SLConfigDescrTag */ |
129 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
|
130 freereturn(s,0); |
5305 | 131 } |
132 | |
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
|
133 /* Note: SLConfig is usually constant value 2, size 1Byte */ |
5333 | 134 esds->SLConfigLen = len = mp4_read_descr_len(s); |
5305 | 135 esds->SLConfig = malloc(esds->SLConfigLen); |
136 if (esds->SLConfig) { | |
137 stream_read(s, esds->SLConfig, esds->SLConfigLen); | |
138 } else { | |
139 esds->SLConfigLen = 0; | |
140 } | |
141 mp_msg(MSGT_DEMUX, MP4_DL, | |
142 "ESDS MPEG4 Sync Layer Config Descriptor (%dBytes)\n" | |
143 " -> predefined: %d\n", len, esds->SLConfig[0]); | |
144 | |
5301 | 145 /* will skip the remainder of the atom */ |
5303 | 146 freereturn(s,0); |
5301 | 147 |
148 } | |
149 | |
5305 | 150 /* cleanup all mem occupied by mp4_parse_esds */ |
151 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
|
152 if(esds->decoderConfigLen) |
5305 | 153 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
|
154 if(esds->SLConfigLen) |
5305 | 155 free(esds->SLConfig); |
156 } | |
157 | |
5303 | 158 #undef freereturn |
159 #undef MP4_DL | |
160 |