1 /*
2 * The contents of this file are subject to the Mozilla Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/MPL/
6 *
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
11 *
12 * The Original Code is MPEG4IP.
13 *
14 * The Initial Developer of the Original Code is Cisco Systems Inc.
15 * Portions created by Cisco Systems Inc. are
16 * Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
17 *
18 * Contributor(s):
19 * Dave Mackie dmackie@cisco.com
20 */
21
22 #ifndef __MP4_UTIL_INCLUDED__
23 #define __MP4_UTIL_INCLUDED__
24 #include <assert.h>
25
26 #ifndef ASSERT
27 #define ASSERT(expr) \
28 if (!(expr)) { \
29 throw new MP4Error("assert failure", __STRING((expr))); \
30 }
31 #endif
32 #define WARNING(expr) \
33 if (expr) { \
34 fflush(stdout); \
35 fprintf(stderr, "Warning (%s) in %s at line %u\n", \
36 __STRING(expr), __FILE__, __LINE__); \
37 }
38
39 #define VERBOSE(exprverbosity, verbosity, expr) \
40 if (((exprverbosity) & (verbosity)) == (exprverbosity)) { expr; }
41
42 #define VERBOSE_ERROR(verbosity, expr) \
43 VERBOSE(MP4_DETAILS_ERROR, verbosity, expr)
44
45 #define VERBOSE_WARNING(verbosity, expr) \
46 VERBOSE(MP4_DETAILS_WARNING, verbosity, expr)
47
48 #define VERBOSE_READ(verbosity, expr) \
49 VERBOSE(MP4_DETAILS_READ, verbosity, expr)
50
51 #define VERBOSE_READ_TABLE(verbosity, expr) \
52 VERBOSE((MP4_DETAILS_READ | MP4_DETAILS_TABLE), verbosity, expr)
53
54 #define VERBOSE_READ_SAMPLE(verbosity, expr) \
55 VERBOSE((MP4_DETAILS_READ | MP4_DETAILS_SAMPLE), verbosity, expr)
56
57 #define VERBOSE_READ_HINT(verbosity, expr) \
58 VERBOSE((MP4_DETAILS_READ | MP4_DETAILS_HINT), verbosity, expr)
59
60 #define VERBOSE_WRITE(verbosity, expr) \
61 VERBOSE(MP4_DETAILS_WRITE, verbosity, expr)
62
63 #define VERBOSE_WRITE_TABLE(verbosity, expr) \
64 VERBOSE((MP4_DETAILS_WRITE | MP4_DETAILS_TABLE), verbosity, expr)
65
66 #define VERBOSE_WRITE_SAMPLE(verbosity, expr) \
67 VERBOSE((MP4_DETAILS_WRITE | MP4_DETAILS_SAMPLE), verbosity, expr)
68
69 #define VERBOSE_WRITE_HINT(verbosity, expr) \
70 VERBOSE((MP4_DETAILS_WRITE | MP4_DETAILS_HINT), verbosity, expr)
71
72 #define VERBOSE_FIND(verbosity, expr) \
73 VERBOSE(MP4_DETAILS_FIND, verbosity, expr)
74
75 #define VERBOSE_ISMA(verbosity, expr) \
76 VERBOSE(MP4_DETAILS_ISMA, verbosity, expr)
77
78 #define VERBOSE_EDIT(verbosity, expr) \
79 VERBOSE(MP4_DETAILS_EDIT, verbosity, expr)
80
Indent(FILE * pFile,u_int8_t depth)81 inline void Indent(FILE* pFile, u_int8_t depth) {
82 fprintf(pFile, "%*c", depth, ' ');
83 }
84
85 static inline void MP4Printf(const char* fmt, ...)
86 #ifndef _WIN32
87 __attribute__((format(__printf__, 1, 2)))
88 #endif
89 ;
90
MP4Printf(const char * fmt,...)91 static inline void MP4Printf(const char* fmt, ...)
92 {
93 va_list ap;
94 va_start(ap, fmt);
95 // TBD API call to set error_msg_func instead of just printf
96 vprintf(fmt, ap);
97 va_end(ap);
98 }
99
100 class MP4Error {
101 public:
MP4Error()102 MP4Error() {
103 m_errno = 0;
104 m_errstring = NULL;
105 m_where = NULL;
106 m_free = 0;
107 }
~MP4Error()108 ~MP4Error() {
109 if (m_free != 0) {
110 free((void *)m_errstring);
111 }
112 }
113 MP4Error(int err, const char* where = NULL) {
114 m_errno = err;
115 m_errstring = NULL;
116 m_where = where;
117 m_free = 0;
118 }
MP4Error(const char * format,const char * where,...)119 MP4Error(const char *format, const char *where, ...) {
120 char *string;
121 m_errno = 0;
122 string = (char *)malloc(512);
123 m_where = where;
124 if (string) {
125 va_list ap;
126 va_start(ap, where);
127 vsnprintf(string, 512, format, ap);
128 va_end(ap);
129 m_errstring = string;
130 m_free = 1;
131 } else {
132 m_errstring = format;
133 m_free = 0;
134 }
135 }
MP4Error(int err,const char * format,const char * where,...)136 MP4Error(int err, const char* format, const char* where, ...) {
137 char *string;
138 m_errno = err;
139 string = (char *)malloc(512);
140 m_where = where;
141 if (string) {
142 va_list ap;
143 va_start(ap, where);
144 vsnprintf(string, 512, format, ap);
145 va_end(ap);
146 m_errstring = string;
147 m_free = 1;
148 } else {
149 m_errstring = format;
150 m_free = 0;
151 }
152 }
153
154 void Print(FILE* pFile = stderr);
155 int m_free;
156 int m_errno;
157 const char* m_errstring;
158 const char* m_where;
159 };
160
161 void MP4HexDump(
162 u_int8_t* pBytes, u_int32_t numBytes,
163 FILE* pFile = stdout, u_int8_t indent = 0);
164
MP4Malloc(size_t size)165 inline void* MP4Malloc(size_t size) {
166 if (size == 0) return NULL;
167 void* p = malloc(size);
168 if (p == NULL && size > 0) {
169 throw new MP4Error(errno);
170 }
171 return p;
172 }
173
MP4Calloc(size_t size)174 inline void* MP4Calloc(size_t size) {
175 if (size == 0) return NULL;
176 return memset(MP4Malloc(size), 0, size);
177 }
178
MP4Stralloc(const char * s1)179 inline char* MP4Stralloc(const char* s1) {
180 char* s2 = (char*)MP4Malloc(strlen(s1) + 1);
181 strcpy(s2, s1);
182 return s2;
183 }
184
185 #ifdef _WIN32
MP4Stralloc(const wchar_t * s1)186 inline wchar_t* MP4Stralloc(const wchar_t* s1) {
187 wchar_t* s2 = (wchar_t*)MP4Malloc((wcslen(s1) + 1)*sizeof(wchar_t));
188 wcscpy(s2, s1);
189 return s2;
190 }
191 #endif
192
MP4Realloc(void * p,u_int32_t newSize)193 inline void* MP4Realloc(void* p, u_int32_t newSize) {
194 // workaround library bug
195 if (p == NULL && newSize == 0) {
196 return NULL;
197 }
198 p = realloc(p, newSize);
199 if (p == NULL && newSize > 0) {
200 throw new MP4Error(errno);
201 }
202 return p;
203 }
204
STRTOINT32(const char * s)205 inline u_int32_t STRTOINT32(const char* s) {
206 return ntohl(*(uint32_t *)s);
207 }
208
INT32TOSTR(u_int32_t i,char * s)209 inline void INT32TOSTR(u_int32_t i, char* s) {
210 *(uint32_t *)s = htonl(i);
211 s[4] = 0;
212 }
213
MP4GetAbsTimestamp()214 inline MP4Timestamp MP4GetAbsTimestamp() {
215 struct timeval tv;
216 gettimeofday(&tv, NULL);
217 MP4Timestamp ret;
218 ret = tv.tv_sec;
219 ret += 2082844800;
220 return ret; // MP4 start date is 1/1/1904
221 // 208284480 is (((1970 - 1904) * 365) + 17) * 24 * 60 * 60
222 }
223
224 u_int64_t MP4ConvertTime(u_int64_t t,
225 u_int32_t oldTimeScale, u_int32_t newTimeScale);
226
227 bool MP4NameFirstMatches(const char* s1, const char* s2);
228
229 bool MP4NameFirstIndex(const char* s, u_int32_t* pIndex);
230
231 char* MP4NameFirst(const char *s);
232
233 const char* MP4NameAfterFirst(const char *s);
234
235 char* MP4ToBase16(const u_int8_t* pData, u_int32_t dataSize);
236
237 char* MP4ToBase64(const u_int8_t* pData, u_int32_t dataSize);
238
239 const char* MP4NormalizeTrackType(const char* type,
240 uint32_t verbosity);
241
242 #endif /* __MP4_UTIL_INCLUDED__ */
243