16
|
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 - 2005. All Rights Reserved.
|
|
17 *
|
|
18 * 3GPP features implementation is based on 3GPP's TS26.234-v5.60,
|
|
19 * and was contributed by Ximpo Group Ltd.
|
|
20 *
|
|
21 * Portions created by Ximpo Group Ltd. are
|
|
22 * Copyright (C) Ximpo Group Ltd. 2003, 2004. All Rights Reserved.
|
|
23 *
|
|
24 * Contributor(s):
|
|
25 * Dave Mackie dmackie@cisco.com
|
|
26 * Alix Marchandise-Franquet alix@cisco.com
|
|
27 * Ximpo Group Ltd. mp4v2@ximpo.com
|
|
28 * Bill May wmay@cisco.com
|
|
29 */
|
|
30
|
|
31 /*
|
|
32 * MP4 library API functions
|
|
33 *
|
|
34 * These are wrapper functions that provide C linkage conventions
|
|
35 * to the library, and catch any internal errors, ensuring that
|
|
36 * a proper return value is given.
|
|
37 */
|
|
38
|
|
39 #include "mp4common.h"
|
|
40
|
|
41 #define PRINT_ERROR(e) \
|
|
42 VERBOSE_ERROR(((MP4File*)hFile)->GetVerbosity(), e->Print());
|
|
43
|
|
44 /* file operations */
|
|
45
|
|
46 extern "C" MP4FileHandle MP4Read(const char* fileName, u_int32_t verbosity)
|
|
47 {
|
|
48 MP4File* pFile = NULL;
|
|
49 try {
|
|
50 pFile = new MP4File(verbosity);
|
|
51 pFile->Read(fileName);
|
|
52 return (MP4FileHandle)pFile;
|
|
53 }
|
|
54 catch (MP4Error* e) {
|
|
55 VERBOSE_ERROR(verbosity, e->Print());
|
|
56 delete e;
|
|
57 delete pFile;
|
|
58 return MP4_INVALID_FILE_HANDLE;
|
|
59 }
|
|
60 }
|
|
61
|
|
62 extern "C" MP4FileHandle MP4Create (const char* fileName,
|
|
63 u_int32_t verbosity,
|
|
64 u_int32_t flags)
|
|
65 {
|
|
66 return MP4CreateEx(fileName, verbosity, flags);
|
|
67 }
|
|
68
|
|
69 extern "C" MP4FileHandle MP4CreateEx (const char* fileName,
|
|
70 u_int32_t verbosity,
|
|
71 u_int32_t flags,
|
|
72 int add_ftyp,
|
|
73 int add_iods,
|
|
74 char* majorBrand,
|
|
75 u_int32_t minorVersion,
|
|
76 char** supportedBrands,
|
|
77 u_int32_t supportedBrandsCount)
|
|
78 {
|
|
79 MP4File* pFile = NULL;
|
|
80 try {
|
|
81 pFile = new MP4File(verbosity);
|
|
82 // LATER useExtensibleFormat, moov first, then mvex's
|
|
83 pFile->Create(fileName, flags, add_ftyp, add_iods,
|
|
84 majorBrand, minorVersion,
|
|
85 supportedBrands, supportedBrandsCount);
|
|
86 return (MP4FileHandle)pFile;
|
|
87 }
|
|
88 catch (MP4Error* e) {
|
|
89 VERBOSE_ERROR(verbosity, e->Print());
|
|
90 delete e;
|
|
91 delete pFile;
|
|
92 return MP4_INVALID_FILE_HANDLE;
|
|
93 }
|
|
94 }
|
|
95
|
|
96 extern "C" MP4FileHandle MP4Modify(const char* fileName,
|
|
97 u_int32_t verbosity, u_int32_t flags)
|
|
98 {
|
|
99 MP4File* pFile = NULL;
|
|
100 try {
|
|
101 pFile = new MP4File(verbosity);
|
|
102 // LATER useExtensibleFormat, moov first, then mvex's
|
|
103 pFile->Modify(fileName);
|
|
104 return (MP4FileHandle)pFile;
|
|
105 }
|
|
106 catch (MP4Error* e) {
|
|
107 VERBOSE_ERROR(verbosity, e->Print());
|
|
108 delete e;
|
|
109 delete pFile;
|
|
110 return MP4_INVALID_FILE_HANDLE;
|
|
111 }
|
|
112 }
|
|
113
|
|
114 extern "C" bool MP4Optimize(const char* existingFileName,
|
|
115 const char* newFileName,
|
|
116 u_int32_t verbosity)
|
|
117 {
|
|
118 try {
|
|
119 MP4File* pFile = new MP4File(verbosity);
|
|
120 pFile->Optimize(existingFileName, newFileName);
|
|
121 delete pFile;
|
|
122 return true;
|
|
123 }
|
|
124 catch (MP4Error* e) {
|
|
125 VERBOSE_ERROR(verbosity, e->Print());
|
|
126 delete e;
|
|
127 }
|
|
128 return false;
|
|
129 }
|
|
130
|
|
131 extern "C" bool MP4Close(MP4FileHandle hFile)
|
|
132 {
|
|
133 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
134 try {
|
|
135 ((MP4File*)hFile)->Close();
|
|
136 delete (MP4File*)hFile;
|
|
137 return true;
|
|
138 }
|
|
139 catch (MP4Error* e) {
|
|
140 PRINT_ERROR(e);
|
|
141 delete e;
|
|
142 }
|
|
143 }
|
|
144 return false;
|
|
145 }
|
|
146
|
|
147 extern "C" bool MP4Dump(
|
|
148 MP4FileHandle hFile,
|
|
149 FILE* pDumpFile,
|
|
150 bool dumpImplicits)
|
|
151 {
|
|
152 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
153 try {
|
|
154 ((MP4File*)hFile)->Dump(pDumpFile, dumpImplicits);
|
|
155 return true;
|
|
156 }
|
|
157 catch (MP4Error* e) {
|
|
158 PRINT_ERROR(e);
|
|
159 delete e;
|
|
160 }
|
|
161 }
|
|
162 return false;
|
|
163 }
|
|
164
|
|
165
|
|
166 /* specific file properties */
|
|
167
|
|
168 extern "C" u_int32_t MP4GetVerbosity(MP4FileHandle hFile)
|
|
169 {
|
|
170 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
171 try {
|
|
172 return ((MP4File*)hFile)->GetVerbosity();
|
|
173 }
|
|
174 catch (MP4Error* e) {
|
|
175 PRINT_ERROR(e);
|
|
176 delete e;
|
|
177 }
|
|
178 }
|
|
179 return 0;
|
|
180 }
|
|
181
|
|
182 extern "C" bool MP4SetVerbosity(MP4FileHandle hFile, u_int32_t verbosity)
|
|
183 {
|
|
184 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
185 try {
|
|
186 ((MP4File*)hFile)->SetVerbosity(verbosity);
|
|
187 return true;
|
|
188 }
|
|
189 catch (MP4Error* e) {
|
|
190 PRINT_ERROR(e);
|
|
191 delete e;
|
|
192 }
|
|
193 }
|
|
194 return false;
|
|
195 }
|
|
196
|
|
197 extern "C" MP4Duration MP4GetDuration(MP4FileHandle hFile)
|
|
198 {
|
|
199 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
200 try {
|
|
201 return ((MP4File*)hFile)->GetDuration();
|
|
202 }
|
|
203 catch (MP4Error* e) {
|
|
204 PRINT_ERROR(e);
|
|
205 delete e;
|
|
206 }
|
|
207 }
|
|
208 return MP4_INVALID_DURATION;
|
|
209 }
|
|
210
|
|
211 extern "C" u_int32_t MP4GetTimeScale(MP4FileHandle hFile)
|
|
212 {
|
|
213 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
214 try {
|
|
215 return ((MP4File*)hFile)->GetTimeScale();
|
|
216 }
|
|
217 catch (MP4Error* e) {
|
|
218 PRINT_ERROR(e);
|
|
219 delete e;
|
|
220 }
|
|
221 }
|
|
222 return 0;
|
|
223 }
|
|
224
|
|
225 extern "C" bool MP4SetTimeScale(MP4FileHandle hFile, u_int32_t value)
|
|
226 {
|
|
227 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
228 try {
|
|
229 ((MP4File*)hFile)->SetTimeScale(value);
|
|
230 return true;
|
|
231 }
|
|
232 catch (MP4Error* e) {
|
|
233 PRINT_ERROR(e);
|
|
234 delete e;
|
|
235 }
|
|
236 }
|
|
237 return false;
|
|
238 }
|
|
239
|
|
240 extern "C" u_int8_t MP4GetODProfileLevel(MP4FileHandle hFile)
|
|
241 {
|
|
242 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
243 try {
|
|
244 return ((MP4File*)hFile)->GetODProfileLevel();
|
|
245 }
|
|
246 catch (MP4Error* e) {
|
|
247 PRINT_ERROR(e);
|
|
248 delete e;
|
|
249 }
|
|
250 }
|
|
251 return 0;
|
|
252 }
|
|
253
|
|
254 extern "C" bool MP4SetODProfileLevel(MP4FileHandle hFile, u_int8_t value)
|
|
255 {
|
|
256 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
257 try {
|
|
258 ((MP4File*)hFile)->SetODProfileLevel(value);
|
|
259 return true;
|
|
260 }
|
|
261 catch (MP4Error* e) {
|
|
262 PRINT_ERROR(e);
|
|
263 delete e;
|
|
264 }
|
|
265 }
|
|
266 return false;
|
|
267 }
|
|
268
|
|
269 extern "C" u_int8_t MP4GetSceneProfileLevel(MP4FileHandle hFile)
|
|
270 {
|
|
271 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
272 try {
|
|
273 return ((MP4File*)hFile)->GetSceneProfileLevel();
|
|
274 }
|
|
275 catch (MP4Error* e) {
|
|
276 PRINT_ERROR(e);
|
|
277 delete e;
|
|
278 }
|
|
279 }
|
|
280 return 0;
|
|
281 }
|
|
282
|
|
283 extern "C" bool MP4SetSceneProfileLevel(MP4FileHandle hFile, u_int8_t value)
|
|
284 {
|
|
285 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
286 try {
|
|
287 ((MP4File*)hFile)->SetSceneProfileLevel(value);
|
|
288 return true;
|
|
289 }
|
|
290 catch (MP4Error* e) {
|
|
291 PRINT_ERROR(e);
|
|
292 delete e;
|
|
293 }
|
|
294 }
|
|
295 return false;
|
|
296 }
|
|
297
|
|
298 extern "C" u_int8_t MP4GetVideoProfileLevel(MP4FileHandle hFile)
|
|
299 {
|
|
300 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
301 try {
|
|
302 return ((MP4File*)hFile)->GetVideoProfileLevel();
|
|
303 }
|
|
304 catch (MP4Error* e) {
|
|
305 PRINT_ERROR(e);
|
|
306 delete e;
|
|
307 }
|
|
308 }
|
|
309 return 0;
|
|
310 }
|
|
311
|
|
312 extern "C" bool MP4SetVideoProfileLevel(MP4FileHandle hFile, u_int8_t value)
|
|
313 {
|
|
314 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
315 try {
|
|
316 ((MP4File*)hFile)->SetVideoProfileLevel(value);
|
|
317 return true;
|
|
318 }
|
|
319 catch (MP4Error* e) {
|
|
320 PRINT_ERROR(e);
|
|
321 delete e;
|
|
322 }
|
|
323 }
|
|
324 return false;
|
|
325 }
|
|
326
|
|
327 extern "C" u_int8_t MP4GetAudioProfileLevel(MP4FileHandle hFile)
|
|
328 {
|
|
329 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
330 try {
|
|
331 return ((MP4File*)hFile)->GetAudioProfileLevel();
|
|
332 }
|
|
333 catch (MP4Error* e) {
|
|
334 PRINT_ERROR(e);
|
|
335 delete e;
|
|
336 }
|
|
337 }
|
|
338 return 0;
|
|
339 }
|
|
340
|
|
341 extern "C" bool MP4SetAudioProfileLevel(MP4FileHandle hFile, u_int8_t value)
|
|
342 {
|
|
343 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
344 try {
|
|
345 ((MP4File*)hFile)->SetAudioProfileLevel(value);
|
|
346 return true;
|
|
347 }
|
|
348 catch (MP4Error* e) {
|
|
349 PRINT_ERROR(e);
|
|
350 delete e;
|
|
351 }
|
|
352 }
|
|
353 return false;
|
|
354 }
|
|
355
|
|
356 extern "C" u_int8_t MP4GetGraphicsProfileLevel(MP4FileHandle hFile)
|
|
357 {
|
|
358 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
359 try {
|
|
360 return ((MP4File*)hFile)->GetGraphicsProfileLevel();
|
|
361 }
|
|
362 catch (MP4Error* e) {
|
|
363 PRINT_ERROR(e);
|
|
364 delete e;
|
|
365 }
|
|
366 }
|
|
367 return 0;
|
|
368 }
|
|
369
|
|
370 extern "C" bool MP4SetGraphicsProfileLevel(MP4FileHandle hFile, u_int8_t value)
|
|
371 {
|
|
372 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
373 try {
|
|
374 ((MP4File*)hFile)->SetGraphicsProfileLevel(value);
|
|
375 return true;
|
|
376 }
|
|
377 catch (MP4Error* e) {
|
|
378 PRINT_ERROR(e);
|
|
379 delete e;
|
|
380 }
|
|
381 }
|
|
382 return false;
|
|
383 }
|
|
384
|
|
385 /* generic file properties */
|
|
386
|
|
387 extern "C" u_int64_t MP4GetIntegerProperty(
|
|
388 MP4FileHandle hFile, const char* propName)
|
|
389 {
|
|
390 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
391 try {
|
|
392 return ((MP4File*)hFile)->GetIntegerProperty(propName);
|
|
393 }
|
|
394 catch (MP4Error* e) {
|
|
395 PRINT_ERROR(e);
|
|
396 delete e;
|
|
397 }
|
|
398 }
|
|
399 return (u_int64_t)-1;
|
|
400 }
|
|
401
|
|
402 extern "C" float MP4GetFloatProperty(
|
|
403 MP4FileHandle hFile, const char* propName)
|
|
404 {
|
|
405 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
406 try {
|
|
407 return ((MP4File*)hFile)->GetFloatProperty(propName);
|
|
408 }
|
|
409 catch (MP4Error* e) {
|
|
410 PRINT_ERROR(e);
|
|
411 delete e;
|
|
412 }
|
|
413 }
|
|
414 return NAN;
|
|
415 }
|
|
416
|
|
417 extern "C" const char* MP4GetStringProperty(
|
|
418 MP4FileHandle hFile, const char* propName)
|
|
419 {
|
|
420 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
421 try {
|
|
422 return ((MP4File*)hFile)->GetStringProperty(propName);
|
|
423 }
|
|
424 catch (MP4Error* e) {
|
|
425 PRINT_ERROR(e);
|
|
426 delete e;
|
|
427 }
|
|
428 }
|
|
429 return NULL;
|
|
430 }
|
|
431
|
|
432 extern "C" void MP4GetBytesProperty(
|
|
433 MP4FileHandle hFile, const char* propName,
|
|
434 u_int8_t** ppValue, u_int32_t* pValueSize)
|
|
435 {
|
|
436 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
437 try {
|
|
438 ((MP4File*)hFile)->GetBytesProperty(propName, ppValue, pValueSize);
|
|
439 return;
|
|
440 }
|
|
441 catch (MP4Error* e) {
|
|
442 PRINT_ERROR(e);
|
|
443 delete e;
|
|
444 }
|
|
445 }
|
|
446 *ppValue = NULL;
|
|
447 *pValueSize = 0;
|
|
448 return;
|
|
449 }
|
|
450
|
|
451 extern "C" bool MP4SetIntegerProperty(
|
|
452 MP4FileHandle hFile, const char* propName, int64_t value)
|
|
453 {
|
|
454 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
455 try {
|
|
456 ((MP4File*)hFile)->SetIntegerProperty(propName, value);
|
|
457 return true;
|
|
458 }
|
|
459 catch (MP4Error* e) {
|
|
460 PRINT_ERROR(e);
|
|
461 delete e;
|
|
462 }
|
|
463 }
|
|
464 return false;
|
|
465 }
|
|
466
|
|
467 extern "C" bool MP4SetFloatProperty(
|
|
468 MP4FileHandle hFile, const char* propName, float value)
|
|
469 {
|
|
470 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
471 try {
|
|
472 ((MP4File*)hFile)->SetFloatProperty(propName, value);
|
|
473 return true;
|
|
474 }
|
|
475 catch (MP4Error* e) {
|
|
476 PRINT_ERROR(e);
|
|
477 delete e;
|
|
478 }
|
|
479 }
|
|
480 return false;
|
|
481 }
|
|
482
|
|
483 extern "C" bool MP4SetStringProperty(
|
|
484 MP4FileHandle hFile, const char* propName, const char* value)
|
|
485 {
|
|
486 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
487 try {
|
|
488 ((MP4File*)hFile)->SetStringProperty(propName, value);
|
|
489 return true;
|
|
490 }
|
|
491 catch (MP4Error* e) {
|
|
492 PRINT_ERROR(e);
|
|
493 delete e;
|
|
494 }
|
|
495 }
|
|
496 return false;
|
|
497 }
|
|
498
|
|
499 extern "C" bool MP4SetBytesProperty(
|
|
500 MP4FileHandle hFile, const char* propName,
|
|
501 const u_int8_t* pValue, u_int32_t valueSize)
|
|
502 {
|
|
503 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
504 try {
|
|
505 ((MP4File*)hFile)->SetBytesProperty(propName, pValue, valueSize);
|
|
506 return true;
|
|
507 }
|
|
508 catch (MP4Error* e) {
|
|
509 PRINT_ERROR(e);
|
|
510 delete e;
|
|
511 }
|
|
512 }
|
|
513 return false;
|
|
514 }
|
|
515
|
|
516 /* track operations */
|
|
517
|
|
518 extern "C" MP4TrackId MP4AddTrack(
|
|
519 MP4FileHandle hFile, const char* type)
|
|
520 {
|
|
521 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
522 try {
|
|
523 return ((MP4File*)hFile)->AddSystemsTrack(type);
|
|
524 }
|
|
525 catch (MP4Error* e) {
|
|
526 PRINT_ERROR(e);
|
|
527 delete e;
|
|
528 }
|
|
529 }
|
|
530 return MP4_INVALID_TRACK_ID;
|
|
531 }
|
|
532
|
|
533 extern "C" MP4TrackId MP4AddSystemsTrack(
|
|
534 MP4FileHandle hFile, const char* type)
|
|
535 {
|
|
536 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
537 try {
|
|
538 return ((MP4File*)hFile)->AddSystemsTrack(type);
|
|
539 }
|
|
540 catch (MP4Error* e) {
|
|
541 PRINT_ERROR(e);
|
|
542 delete e;
|
|
543 }
|
|
544 }
|
|
545 return MP4_INVALID_TRACK_ID;
|
|
546 }
|
|
547
|
|
548 extern "C" MP4TrackId MP4AddODTrack(MP4FileHandle hFile)
|
|
549 {
|
|
550 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
551 try {
|
|
552 return ((MP4File*)hFile)->AddODTrack();
|
|
553 }
|
|
554 catch (MP4Error* e) {
|
|
555 PRINT_ERROR(e);
|
|
556 delete e;
|
|
557 }
|
|
558 }
|
|
559 return MP4_INVALID_TRACK_ID;
|
|
560 }
|
|
561
|
|
562 extern "C" MP4TrackId MP4AddSceneTrack(MP4FileHandle hFile)
|
|
563 {
|
|
564 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
565 try {
|
|
566 return ((MP4File*)hFile)->AddSceneTrack();
|
|
567 }
|
|
568 catch (MP4Error* e) {
|
|
569 PRINT_ERROR(e);
|
|
570 delete e;
|
|
571 }
|
|
572 }
|
|
573 return MP4_INVALID_TRACK_ID;
|
|
574 }
|
|
575
|
|
576 extern "C" MP4TrackId MP4AddAudioTrack(
|
|
577 MP4FileHandle hFile,
|
|
578 u_int32_t timeScale,
|
|
579 MP4Duration sampleDuration,
|
|
580 u_int8_t audioType)
|
|
581 {
|
|
582 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
583 try {
|
|
584 return ((MP4File*)hFile)->
|
|
585 AddAudioTrack(timeScale, sampleDuration, audioType);
|
|
586 }
|
|
587 catch (MP4Error* e) {
|
|
588 PRINT_ERROR(e);
|
|
589 delete e;
|
|
590 }
|
|
591 }
|
|
592 return MP4_INVALID_TRACK_ID;
|
|
593 }
|
|
594
|
|
595 extern "C" MP4TrackId MP4AddEncAudioTrack(MP4FileHandle hFile,
|
|
596 u_int32_t timeScale,
|
|
597 MP4Duration sampleDuration,
|
|
598 mp4v2_ismacrypParams *icPp,
|
|
599 u_int8_t audioType
|
|
600 )
|
|
601 {
|
|
602 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
603 try {
|
|
604 return ((MP4File*)hFile)->
|
|
605 AddEncAudioTrack(timeScale, sampleDuration, audioType,
|
|
606 icPp->scheme_type, icPp->scheme_version,
|
|
607 icPp->key_ind_len, icPp->iv_len,
|
|
608 icPp->selective_enc, icPp->kms_uri);
|
|
609 }
|
|
610 catch (MP4Error* e) {
|
|
611 PRINT_ERROR(e);
|
|
612 delete e;
|
|
613 }
|
|
614 }
|
|
615 return MP4_INVALID_TRACK_ID;
|
|
616 }
|
|
617 extern "C" MP4TrackId MP4AddAmrAudioTrack(
|
|
618 MP4FileHandle hFile,
|
|
619 u_int32_t timeScale,
|
|
620 u_int16_t modeSet,
|
|
621 u_int8_t modeChangePeriod,
|
|
622 u_int8_t framesPerSample,
|
|
623 bool isAmrWB)
|
|
624 {
|
|
625 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
626 try {
|
|
627 return ((MP4File*)hFile)->
|
|
628 AddAmrAudioTrack(timeScale, modeSet, modeChangePeriod, framesPerSample, isAmrWB);
|
|
629 }
|
|
630 catch (MP4Error* e) {
|
|
631 PRINT_ERROR(e);
|
|
632 delete e;
|
|
633 }
|
|
634 }
|
|
635 return MP4_INVALID_TRACK_ID;
|
|
636 }
|
|
637
|
|
638 extern "C" void MP4SetAmrVendor(
|
|
639 MP4FileHandle hFile,
|
|
640 MP4TrackId trackId,
|
|
641 u_int32_t vendor)
|
|
642 {
|
|
643 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
644 try {
|
|
645 ((MP4File*)hFile)->
|
|
646 SetAmrVendor(trackId, vendor);
|
|
647 }
|
|
648 catch (MP4Error* e) {
|
|
649 PRINT_ERROR(e);
|
|
650 delete e;
|
|
651 }
|
|
652 }
|
|
653 }
|
|
654
|
|
655 extern "C" void MP4SetAmrDecoderVersion(
|
|
656 MP4FileHandle hFile,
|
|
657 MP4TrackId trackId,
|
|
658 u_int8_t decoderVersion)
|
|
659 {
|
|
660 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
661 try {
|
|
662 ((MP4File*)hFile)->
|
|
663 SetAmrDecoderVersion(trackId, decoderVersion);
|
|
664 }
|
|
665 catch (MP4Error* e) {
|
|
666 PRINT_ERROR(e);
|
|
667 delete e;
|
|
668 }
|
|
669 }
|
|
670 }
|
|
671
|
|
672 extern "C" void MP4SetAmrModeSet(
|
|
673 MP4FileHandle hFile,
|
|
674 MP4TrackId trackId,
|
|
675 u_int16_t modeSet)
|
|
676 {
|
|
677 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
678 try {
|
|
679 ((MP4File*)hFile)->
|
|
680 SetAmrModeSet(trackId, modeSet);
|
|
681 }
|
|
682 catch (MP4Error* e) {
|
|
683 PRINT_ERROR(e);
|
|
684 delete e;
|
|
685 }
|
|
686 }
|
|
687 }
|
|
688
|
|
689 extern "C" uint16_t MP4GetAmrModeSet(
|
|
690 MP4FileHandle hFile,
|
|
691 MP4TrackId trackId)
|
|
692 {
|
|
693 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
694 try {
|
|
695 return ((MP4File*)hFile)->
|
|
696 GetAmrModeSet(trackId);
|
|
697 }
|
|
698 catch (MP4Error* e) {
|
|
699 PRINT_ERROR(e);
|
|
700 delete e;
|
|
701 }
|
|
702 }
|
|
703 return 0;
|
|
704 }
|
|
705
|
|
706 extern "C" MP4TrackId MP4AddHrefTrack (MP4FileHandle hFile,
|
|
707 uint32_t timeScale,
|
|
708 MP4Duration sampleDuration)
|
|
709 {
|
|
710 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
711 try {
|
|
712 MP4File *pFile = (MP4File *)hFile;
|
|
713
|
|
714 return pFile->AddHrefTrack(timeScale,
|
|
715 sampleDuration);
|
|
716 }
|
|
717 catch (MP4Error* e) {
|
|
718 PRINT_ERROR(e);
|
|
719 delete e;
|
|
720 }
|
|
721 }
|
|
722 return MP4_INVALID_TRACK_ID;
|
|
723 }
|
|
724
|
|
725 extern "C" MP4TrackId MP4AddVideoTrack(
|
|
726 MP4FileHandle hFile,
|
|
727 u_int32_t timeScale,
|
|
728 MP4Duration sampleDuration,
|
|
729 u_int16_t width,
|
|
730 u_int16_t height,
|
|
731 u_int8_t videoType)
|
|
732 {
|
|
733 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
734 try {
|
|
735 MP4File *pFile = (MP4File *)hFile;
|
|
736
|
|
737 return pFile->AddMP4VideoTrack(timeScale,
|
|
738 sampleDuration,
|
|
739 width,
|
|
740 height,
|
|
741 videoType);
|
|
742 }
|
|
743 catch (MP4Error* e) {
|
|
744 PRINT_ERROR(e);
|
|
745 delete e;
|
|
746 }
|
|
747 }
|
|
748 return MP4_INVALID_TRACK_ID;
|
|
749 }
|
|
750
|
|
751 extern "C" MP4TrackId MP4AddEncVideoTrack(MP4FileHandle hFile,
|
|
752 u_int32_t timeScale,
|
|
753 MP4Duration sampleDuration,
|
|
754 u_int16_t width,
|
|
755 u_int16_t height,
|
|
756 mp4v2_ismacrypParams *icPp,
|
|
757 u_int8_t videoType )
|
|
758 {
|
|
759 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
760 try {
|
|
761 return ((MP4File*)hFile)->AddEncVideoTrack(timeScale, sampleDuration,
|
|
762 width, height, videoType,
|
|
763 icPp->scheme_type, icPp->scheme_version,
|
|
764 icPp->key_ind_len, icPp->iv_len,
|
|
765 icPp->selective_enc, icPp->kms_uri);
|
|
766 }
|
|
767 catch (MP4Error* e) {
|
|
768 PRINT_ERROR(e);
|
|
769 delete e;
|
|
770 }
|
|
771 }
|
|
772 return MP4_INVALID_TRACK_ID;
|
|
773 }
|
|
774
|
|
775 extern "C" MP4TrackId MP4AddH264VideoTrack(
|
|
776 MP4FileHandle hFile,
|
|
777 u_int32_t timeScale,
|
|
778 MP4Duration sampleDuration,
|
|
779 u_int16_t width,
|
|
780 u_int16_t height,
|
|
781 uint8_t AVCProfileIndication,
|
|
782 uint8_t profile_compat,
|
|
783 uint8_t AVCLevelIndication,
|
|
784 uint8_t sampleLenFieldSizeMinusOne)
|
|
785 {
|
|
786 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
787 try {
|
|
788 MP4File *pFile = (MP4File *)hFile;
|
|
789
|
|
790 return pFile->AddH264VideoTrack(timeScale,
|
|
791 sampleDuration,
|
|
792 width,
|
|
793 height,
|
|
794 AVCProfileIndication,
|
|
795 profile_compat,
|
|
796 AVCLevelIndication,
|
|
797 sampleLenFieldSizeMinusOne);
|
|
798 }
|
|
799 catch (MP4Error* e) {
|
|
800 PRINT_ERROR(e);
|
|
801 delete e;
|
|
802 }
|
|
803 }
|
|
804 return MP4_INVALID_TRACK_ID;
|
|
805 }
|
|
806
|
|
807 extern "C" bool MP4AddH264SequenceParameterSet (MP4FileHandle hFile,
|
|
808 MP4TrackId trackId,
|
|
809 const uint8_t *pSequence,
|
|
810 uint16_t sequenceLen)
|
|
811 {
|
|
812 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
813 try {
|
|
814 MP4File *pFile = (MP4File *)hFile;
|
|
815
|
|
816 return pFile->AddH264SequenceParameterSet(trackId,
|
|
817 pSequence,
|
|
818 sequenceLen);
|
|
819 }
|
|
820 catch (MP4Error* e) {
|
|
821 PRINT_ERROR(e);
|
|
822 delete e;
|
|
823 }
|
|
824 }
|
|
825 return false;
|
|
826 }
|
|
827 extern "C" bool MP4AddH264PictureParameterSet (MP4FileHandle hFile,
|
|
828 MP4TrackId trackId,
|
|
829 const uint8_t *pPict,
|
|
830 uint16_t pictLen)
|
|
831 {
|
|
832 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
833 try {
|
|
834 MP4File *pFile = (MP4File *)hFile;
|
|
835
|
|
836 return pFile->AddH264PictureParameterSet(trackId,
|
|
837 pPict,
|
|
838 pictLen);
|
|
839 }
|
|
840 catch (MP4Error* e) {
|
|
841 PRINT_ERROR(e);
|
|
842 delete e;
|
|
843 }
|
|
844 }
|
|
845 return false;
|
|
846 }
|
|
847
|
|
848 extern "C" MP4TrackId MP4AddH263VideoTrack(
|
|
849 MP4FileHandle hFile,
|
|
850 u_int32_t timeScale,
|
|
851 MP4Duration sampleDuration,
|
|
852 u_int16_t width,
|
|
853 u_int16_t height,
|
|
854 u_int8_t h263Level,
|
|
855 u_int8_t h263Profile,
|
|
856 u_int32_t avgBitrate,
|
|
857 u_int32_t maxBitrate)
|
|
858 {
|
|
859 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
860 try {
|
|
861 return ((MP4File*)hFile)->
|
|
862 AddH263VideoTrack(timeScale, sampleDuration, width, height, h263Level, h263Profile, avgBitrate, maxBitrate);
|
|
863 }
|
|
864 catch (MP4Error* e) {
|
|
865 PRINT_ERROR(e);
|
|
866 delete e;
|
|
867 }
|
|
868 }
|
|
869
|
|
870 return MP4_INVALID_TRACK_ID;
|
|
871 }
|
|
872
|
|
873 extern "C" void MP4SetH263Vendor(
|
|
874 MP4FileHandle hFile,
|
|
875 MP4TrackId trackId,
|
|
876 u_int32_t vendor)
|
|
877 {
|
|
878 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
879 try {
|
|
880 ((MP4File*)hFile)->
|
|
881 SetH263Vendor(trackId, vendor);
|
|
882 }
|
|
883 catch (MP4Error* e) {
|
|
884 PRINT_ERROR(e);
|
|
885 delete e;
|
|
886 }
|
|
887 }
|
|
888 }
|
|
889
|
|
890 extern "C" void MP4SetH263DecoderVersion(
|
|
891 MP4FileHandle hFile,
|
|
892 MP4TrackId trackId,
|
|
893 u_int8_t decoderVersion)
|
|
894 {
|
|
895 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
896
|
|
897 try {
|
|
898 ((MP4File*)hFile)->
|
|
899 SetH263DecoderVersion(trackId, decoderVersion);
|
|
900 }
|
|
901 catch (MP4Error* e) {
|
|
902 PRINT_ERROR(e);
|
|
903 delete e;
|
|
904 }
|
|
905 }
|
|
906 }
|
|
907
|
|
908 extern "C" void MP4SetH263Bitrates(
|
|
909 MP4FileHandle hFile,
|
|
910 MP4TrackId trackId,
|
|
911 u_int32_t avgBitrate,
|
|
912 u_int32_t maxBitrate)
|
|
913 {
|
|
914 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
915
|
|
916 try {
|
|
917 ((MP4File*)hFile)->
|
|
918 SetH263Bitrates(trackId, avgBitrate, maxBitrate);
|
|
919 }
|
|
920 catch (MP4Error* e) {
|
|
921 PRINT_ERROR(e);
|
|
922 delete e;
|
|
923 }
|
|
924 }
|
|
925 }
|
|
926
|
|
927 extern "C" MP4TrackId MP4AddHintTrack(
|
|
928 MP4FileHandle hFile, MP4TrackId refTrackId)
|
|
929 {
|
|
930 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
931 try {
|
|
932 return ((MP4File*)hFile)->AddHintTrack(refTrackId);
|
|
933 }
|
|
934 catch (MP4Error* e) {
|
|
935 PRINT_ERROR(e);
|
|
936 delete e;
|
|
937 }
|
|
938 }
|
|
939 return MP4_INVALID_TRACK_ID;
|
|
940 }
|
|
941
|
|
942 extern "C" MP4TrackId MP4CloneTrack(
|
|
943 MP4FileHandle srcFile,
|
|
944 MP4TrackId srcTrackId,
|
|
945 MP4FileHandle dstFile,
|
|
946 MP4TrackId dstHintTrackReferenceTrack)
|
|
947 {
|
|
948 MP4TrackId dstTrackId = MP4_INVALID_TRACK_ID;
|
|
949
|
|
950 if (dstFile == NULL) {
|
|
951 dstFile = srcFile;
|
|
952 }
|
|
953
|
|
954 const char* trackType =
|
|
955 MP4GetTrackType(srcFile, srcTrackId);
|
|
956
|
|
957 if (!trackType) {
|
|
958 return dstTrackId;
|
|
959 }
|
|
960
|
|
961 if (MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
|
|
962 MP4SetVideoProfileLevel(dstFile,
|
|
963 MP4GetVideoProfileLevel(srcFile));
|
|
964 dstTrackId = MP4AddVideoTrack(
|
|
965 dstFile,
|
|
966 MP4GetTrackTimeScale(srcFile, srcTrackId),
|
|
967 MP4GetTrackFixedSampleDuration(srcFile, srcTrackId),
|
|
968 MP4GetTrackVideoWidth(srcFile, srcTrackId),
|
|
969 MP4GetTrackVideoHeight(srcFile, srcTrackId),
|
|
970 MP4GetTrackEsdsObjectTypeId(srcFile, srcTrackId));
|
|
971
|
|
972 } else if (MP4_IS_AUDIO_TRACK_TYPE(trackType)) {
|
|
973 MP4SetAudioProfileLevel(dstFile,
|
|
974 MP4GetAudioProfileLevel(srcFile));
|
|
975 dstTrackId = MP4AddAudioTrack(
|
|
976 dstFile,
|
|
977 MP4GetTrackTimeScale(srcFile, srcTrackId),
|
|
978 MP4GetTrackFixedSampleDuration(srcFile, srcTrackId),
|
|
979 MP4GetTrackEsdsObjectTypeId(srcFile, srcTrackId));
|
|
980
|
|
981 } else if (MP4_IS_OD_TRACK_TYPE(trackType)) {
|
|
982 dstTrackId = MP4AddODTrack(dstFile);
|
|
983
|
|
984 } else if (MP4_IS_SCENE_TRACK_TYPE(trackType)) {
|
|
985 dstTrackId = MP4AddSceneTrack(dstFile);
|
|
986
|
|
987 } else if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
|
|
988 if (dstHintTrackReferenceTrack == MP4_INVALID_TRACK_ID) {
|
|
989 dstTrackId = MP4_INVALID_TRACK_ID;
|
|
990 } else {
|
|
991 dstTrackId = MP4AddHintTrack(
|
|
992 dstFile,
|
|
993 dstHintTrackReferenceTrack);
|
|
994 }
|
|
995
|
|
996 } else if (MP4_IS_SYSTEMS_TRACK_TYPE(trackType)) {
|
|
997 dstTrackId = MP4AddSystemsTrack(dstFile, trackType);
|
|
998
|
|
999 } else {
|
|
1000 dstTrackId = MP4AddTrack(dstFile, trackType);
|
|
1001 }
|
|
1002
|
|
1003 if (dstTrackId == MP4_INVALID_TRACK_ID) {
|
|
1004 return dstTrackId;
|
|
1005 }
|
|
1006
|
|
1007 MP4SetTrackTimeScale(
|
|
1008 dstFile,
|
|
1009 dstTrackId,
|
|
1010 MP4GetTrackTimeScale(srcFile, srcTrackId));
|
|
1011
|
|
1012 if (MP4_IS_AUDIO_TRACK_TYPE(trackType)
|
|
1013 || MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
|
|
1014 // copy track ES configuration
|
|
1015 u_int8_t* pConfig = NULL;
|
|
1016 u_int32_t configSize = 0;
|
|
1017
|
|
1018 MP4GetTrackESConfiguration(
|
|
1019 srcFile,
|
|
1020 srcTrackId,
|
|
1021 &pConfig,
|
|
1022 &configSize);
|
|
1023
|
|
1024 MP4SetTrackESConfiguration(
|
|
1025 dstFile,
|
|
1026 dstTrackId,
|
|
1027 pConfig,
|
|
1028 configSize);
|
|
1029
|
|
1030 free(pConfig);
|
|
1031 }
|
|
1032
|
|
1033 if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
|
|
1034 // probably not exactly what is wanted
|
|
1035 // but caller can adjust later to fit their desires
|
|
1036
|
|
1037 char* payloadName = NULL;
|
|
1038 char *encodingParms = NULL;
|
|
1039 u_int8_t payloadNumber;
|
|
1040 u_int16_t maxPayloadSize;
|
|
1041
|
|
1042 MP4GetHintTrackRtpPayload(
|
|
1043 srcFile,
|
|
1044 srcTrackId,
|
|
1045 &payloadName,
|
|
1046 &payloadNumber,
|
|
1047 &maxPayloadSize,
|
|
1048 &encodingParms);
|
|
1049
|
|
1050 MP4SetHintTrackRtpPayload(
|
|
1051 dstFile,
|
|
1052 dstTrackId,
|
|
1053 payloadName,
|
|
1054 &payloadNumber,
|
|
1055 maxPayloadSize,
|
|
1056 encodingParms);
|
|
1057 #if 0
|
|
1058 MP4SetHintTrackSdp(
|
|
1059 dstFile,
|
|
1060 dstTrackId,
|
|
1061 MP4GetHintTrackSdp(srcFile, srcTrackId));
|
|
1062 #endif
|
|
1063 }
|
|
1064
|
|
1065 return dstTrackId;
|
|
1066 }
|
|
1067
|
|
1068 // Given a track, make an encrypted clone of it in the dest. file
|
|
1069 extern "C" MP4TrackId MP4EncAndCloneTrack(MP4FileHandle srcFile,
|
|
1070 MP4TrackId srcTrackId,
|
|
1071 mp4v2_ismacrypParams *icPp,
|
|
1072 MP4FileHandle dstFile,
|
|
1073 MP4TrackId dstHintTrackReferenceTrack
|
|
1074 )
|
|
1075 {
|
|
1076 MP4TrackId dstTrackId = MP4_INVALID_TRACK_ID;
|
|
1077
|
|
1078 if (dstFile == NULL) {
|
|
1079 dstFile = srcFile;
|
|
1080 }
|
|
1081
|
|
1082 const char* trackType =
|
|
1083 MP4GetTrackType(srcFile, srcTrackId);
|
|
1084
|
|
1085 if (!trackType) {
|
|
1086 return dstTrackId;
|
|
1087 }
|
|
1088
|
|
1089 if (MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
|
|
1090 MP4SetVideoProfileLevel(dstFile, MP4GetVideoProfileLevel(srcFile));
|
|
1091 dstTrackId = MP4AddEncVideoTrack(dstFile,
|
|
1092 MP4GetTrackTimeScale(srcFile, srcTrackId),
|
|
1093 MP4GetTrackFixedSampleDuration(srcFile,
|
|
1094 srcTrackId),
|
|
1095 MP4GetTrackVideoWidth(srcFile, srcTrackId),
|
|
1096 MP4GetTrackVideoHeight(srcFile, srcTrackId),
|
|
1097 icPp,
|
|
1098 MP4GetTrackEsdsObjectTypeId(srcFile,
|
|
1099 srcTrackId)
|
|
1100 );
|
|
1101
|
|
1102 } else if (MP4_IS_AUDIO_TRACK_TYPE(trackType)) {
|
|
1103 MP4SetAudioProfileLevel(dstFile, MP4GetAudioProfileLevel(srcFile));
|
|
1104 dstTrackId = MP4AddEncAudioTrack(dstFile,
|
|
1105 MP4GetTrackTimeScale(srcFile, srcTrackId),
|
|
1106 MP4GetTrackFixedSampleDuration(srcFile,
|
|
1107 srcTrackId),
|
|
1108 icPp,
|
|
1109 MP4GetTrackEsdsObjectTypeId(srcFile,
|
|
1110 srcTrackId)
|
|
1111 );
|
|
1112
|
|
1113 } else if (MP4_IS_OD_TRACK_TYPE(trackType)) {
|
|
1114 dstTrackId = MP4AddODTrack(dstFile);
|
|
1115
|
|
1116 } else if (MP4_IS_SCENE_TRACK_TYPE(trackType)) {
|
|
1117 dstTrackId = MP4AddSceneTrack(dstFile);
|
|
1118
|
|
1119 } else if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
|
|
1120 if (dstHintTrackReferenceTrack == MP4_INVALID_TRACK_ID) {
|
|
1121 dstTrackId = MP4_INVALID_TRACK_ID;
|
|
1122 } else {
|
|
1123 dstTrackId = MP4AddHintTrack(dstFile,
|
|
1124 MP4GetHintTrackReferenceTrackId(srcFile,
|
|
1125 srcTrackId));
|
|
1126 }
|
|
1127 } else if (MP4_IS_SYSTEMS_TRACK_TYPE(trackType)) {
|
|
1128 dstTrackId = MP4AddSystemsTrack(dstFile, trackType);
|
|
1129
|
|
1130 } else {
|
|
1131 dstTrackId = MP4AddTrack(dstFile, trackType);
|
|
1132 }
|
|
1133
|
|
1134 if (dstTrackId == MP4_INVALID_TRACK_ID) {
|
|
1135 return dstTrackId;
|
|
1136 }
|
|
1137
|
|
1138 MP4SetTrackTimeScale(dstFile,
|
|
1139 dstTrackId,
|
|
1140 MP4GetTrackTimeScale(srcFile, srcTrackId));
|
|
1141
|
|
1142 if (MP4_IS_AUDIO_TRACK_TYPE(trackType)
|
|
1143 || MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
|
|
1144 // copy track ES configuration
|
|
1145 u_int8_t* pConfig = NULL;
|
|
1146 u_int32_t configSize = 0;
|
|
1147 if (MP4GetTrackESConfiguration(srcFile, srcTrackId,
|
|
1148 &pConfig, &configSize)) {
|
|
1149
|
|
1150 if (pConfig != NULL) {
|
|
1151 MP4SetTrackESConfiguration(dstFile, dstTrackId,
|
|
1152 pConfig, configSize);
|
|
1153 }
|
|
1154 }
|
|
1155 if (pConfig != NULL)
|
|
1156 free(pConfig);
|
|
1157 }
|
|
1158
|
|
1159 // Bill's change to MP4CloneTrack
|
|
1160 if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
|
|
1161 // probably not exactly what is wanted
|
|
1162 // but caller can adjust later to fit their desires
|
|
1163
|
|
1164 char* payloadName = NULL;
|
|
1165 char *encodingParms = NULL;
|
|
1166 u_int8_t payloadNumber;
|
|
1167 u_int16_t maxPayloadSize;
|
|
1168
|
|
1169 MP4GetHintTrackRtpPayload(
|
|
1170 srcFile,
|
|
1171 srcTrackId,
|
|
1172 &payloadName,
|
|
1173 &payloadNumber,
|
|
1174 &maxPayloadSize,
|
|
1175 &encodingParms);
|
|
1176
|
|
1177 MP4SetHintTrackRtpPayload(
|
|
1178 dstFile,
|
|
1179 dstTrackId,
|
|
1180 payloadName,
|
|
1181 &payloadNumber,
|
|
1182 maxPayloadSize,
|
|
1183 encodingParms);
|
|
1184 #if 0
|
|
1185 MP4SetHintTrackSdp(
|
|
1186 dstFile,
|
|
1187 dstTrackId,
|
|
1188 MP4GetHintTrackSdp(srcFile, srcTrackId));
|
|
1189 #endif
|
|
1190 }
|
|
1191
|
|
1192 return dstTrackId;
|
|
1193 }
|
|
1194 extern "C" MP4TrackId MP4CopyTrack(MP4FileHandle srcFile,
|
|
1195 MP4TrackId srcTrackId,
|
|
1196 MP4FileHandle dstFile,
|
|
1197 bool applyEdits,
|
|
1198 MP4TrackId dstHintTrackReferenceTrack)
|
|
1199 {
|
|
1200 bool copySamples = true; // LATER allow false => reference samples
|
|
1201
|
|
1202 MP4TrackId dstTrackId =
|
|
1203 MP4CloneTrack(srcFile, srcTrackId, dstFile, dstHintTrackReferenceTrack);
|
|
1204
|
|
1205 if (dstTrackId == MP4_INVALID_TRACK_ID) {
|
|
1206 return dstTrackId;
|
|
1207 }
|
|
1208
|
|
1209 bool viaEdits =
|
|
1210 applyEdits && MP4GetTrackNumberOfEdits(srcFile, srcTrackId);
|
|
1211
|
|
1212 MP4SampleId sampleId = 0;
|
|
1213 MP4SampleId numSamples =
|
|
1214 MP4GetTrackNumberOfSamples(srcFile, srcTrackId);
|
|
1215
|
|
1216 MP4Timestamp when = 0;
|
|
1217 MP4Duration editsDuration =
|
|
1218 MP4GetTrackEditTotalDuration(srcFile, srcTrackId);
|
|
1219
|
|
1220 while (true) {
|
|
1221 MP4Duration sampleDuration = MP4_INVALID_DURATION;
|
|
1222
|
|
1223 if (viaEdits) {
|
|
1224 sampleId = MP4GetSampleIdFromEditTime(
|
|
1225 srcFile,
|
|
1226 srcTrackId,
|
|
1227 when,
|
|
1228 NULL,
|
|
1229 &sampleDuration);
|
|
1230
|
|
1231 // in theory, this shouldn't happen
|
|
1232 if (sampleId == MP4_INVALID_SAMPLE_ID) {
|
|
1233 MP4DeleteTrack(dstFile, dstTrackId);
|
|
1234 return MP4_INVALID_TRACK_ID;
|
|
1235 }
|
|
1236
|
|
1237 when += sampleDuration;
|
|
1238
|
|
1239 if (when >= editsDuration) {
|
|
1240 break;
|
|
1241 }
|
|
1242 } else {
|
|
1243 sampleId++;
|
|
1244 if (sampleId > numSamples) {
|
|
1245 break;
|
|
1246 }
|
|
1247 }
|
|
1248
|
|
1249 bool rc = false;
|
|
1250
|
|
1251 if (copySamples) {
|
|
1252 rc = MP4CopySample(
|
|
1253 srcFile,
|
|
1254 srcTrackId,
|
|
1255 sampleId,
|
|
1256 dstFile,
|
|
1257 dstTrackId,
|
|
1258 sampleDuration);
|
|
1259
|
|
1260 } else {
|
|
1261 rc = MP4ReferenceSample(
|
|
1262 srcFile,
|
|
1263 srcTrackId,
|
|
1264 sampleId,
|
|
1265 dstFile,
|
|
1266 dstTrackId,
|
|
1267 sampleDuration);
|
|
1268 }
|
|
1269
|
|
1270 if (!rc) {
|
|
1271 MP4DeleteTrack(dstFile, dstTrackId);
|
|
1272 return MP4_INVALID_TRACK_ID;
|
|
1273 }
|
|
1274 }
|
|
1275
|
|
1276 return dstTrackId;
|
|
1277 }
|
|
1278
|
|
1279 // Given a source track in a source file, make an encrypted copy of
|
|
1280 // the track in the destination file, including sample encryption
|
|
1281 extern "C" MP4TrackId MP4EncAndCopyTrack(MP4FileHandle srcFile,
|
|
1282 MP4TrackId srcTrackId,
|
|
1283 mp4v2_ismacrypParams *icPp,
|
|
1284 encryptFunc_t encfcnp,
|
|
1285 u_int32_t encfcnparam1,
|
|
1286 MP4FileHandle dstFile,
|
|
1287 bool applyEdits,
|
|
1288 MP4TrackId dstHintTrackReferenceTrack
|
|
1289 )
|
|
1290 {
|
|
1291 bool copySamples = true; // LATER allow false => reference samples
|
|
1292
|
|
1293 MP4TrackId dstTrackId =
|
|
1294 MP4EncAndCloneTrack(srcFile, srcTrackId,
|
|
1295 icPp,
|
|
1296 dstFile, dstHintTrackReferenceTrack);
|
|
1297
|
|
1298 if (dstTrackId == MP4_INVALID_TRACK_ID) {
|
|
1299 return dstTrackId;
|
|
1300 }
|
|
1301
|
|
1302 bool viaEdits =
|
|
1303 applyEdits && MP4GetTrackNumberOfEdits(srcFile, srcTrackId);
|
|
1304
|
|
1305 MP4SampleId sampleId = 0;
|
|
1306 MP4SampleId numSamples =
|
|
1307 MP4GetTrackNumberOfSamples(srcFile, srcTrackId);
|
|
1308
|
|
1309 MP4Timestamp when = 0;
|
|
1310 MP4Duration editsDuration =
|
|
1311 MP4GetTrackEditTotalDuration(srcFile, srcTrackId);
|
|
1312
|
|
1313 while (true) {
|
|
1314 MP4Duration sampleDuration = MP4_INVALID_DURATION;
|
|
1315
|
|
1316 if (viaEdits) {
|
|
1317 sampleId = MP4GetSampleIdFromEditTime(srcFile,
|
|
1318 srcTrackId,
|
|
1319 when,
|
|
1320 NULL,
|
|
1321 &sampleDuration);
|
|
1322
|
|
1323 // in theory, this shouldn't happen
|
|
1324 if (sampleId == MP4_INVALID_SAMPLE_ID) {
|
|
1325 MP4DeleteTrack(dstFile, dstTrackId);
|
|
1326 return MP4_INVALID_TRACK_ID;
|
|
1327 }
|
|
1328
|
|
1329 when += sampleDuration;
|
|
1330
|
|
1331 if (when >= editsDuration) {
|
|
1332 break;
|
|
1333 }
|
|
1334 } else {
|
|
1335 sampleId++;
|
|
1336 if (sampleId > numSamples) {
|
|
1337 break;
|
|
1338 }
|
|
1339 }
|
|
1340
|
|
1341 bool rc = false;
|
|
1342
|
|
1343 if (copySamples) {
|
|
1344 // encrypt and copy
|
|
1345 rc = MP4EncAndCopySample(srcFile,
|
|
1346 srcTrackId,
|
|
1347 sampleId,
|
|
1348 encfcnp,
|
|
1349 encfcnparam1,
|
|
1350 dstFile,
|
|
1351 dstTrackId,
|
|
1352 sampleDuration);
|
|
1353
|
|
1354 } else {
|
|
1355 // not sure what these are - encrypt?
|
|
1356 rc = MP4ReferenceSample(srcFile,
|
|
1357 srcTrackId,
|
|
1358 sampleId,
|
|
1359 dstFile,
|
|
1360 dstTrackId,
|
|
1361 sampleDuration);
|
|
1362 }
|
|
1363
|
|
1364 if (!rc) {
|
|
1365 MP4DeleteTrack(dstFile, dstTrackId);
|
|
1366 return MP4_INVALID_TRACK_ID;
|
|
1367 }
|
|
1368 }
|
|
1369
|
|
1370 return dstTrackId;
|
|
1371 }
|
|
1372
|
|
1373 extern "C" bool MP4DeleteTrack(
|
|
1374 MP4FileHandle hFile,
|
|
1375 MP4TrackId trackId)
|
|
1376 {
|
|
1377 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1378 try {
|
|
1379 ((MP4File*)hFile)->DeleteTrack(trackId);
|
|
1380 return true;
|
|
1381 }
|
|
1382 catch (MP4Error* e) {
|
|
1383 PRINT_ERROR(e);
|
|
1384 delete e;
|
|
1385 }
|
|
1386 }
|
|
1387 return false;
|
|
1388 }
|
|
1389
|
|
1390 extern "C" u_int32_t MP4GetNumberOfTracks(
|
|
1391 MP4FileHandle hFile,
|
|
1392 const char* type,
|
|
1393 u_int8_t subType)
|
|
1394 {
|
|
1395 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1396 try {
|
|
1397 return ((MP4File*)hFile)->GetNumberOfTracks(type, subType);
|
|
1398 }
|
|
1399 catch (MP4Error* e) {
|
|
1400 PRINT_ERROR(e);
|
|
1401 delete e;
|
|
1402 }
|
|
1403 }
|
|
1404 return 0;
|
|
1405 }
|
|
1406
|
|
1407 extern "C" MP4TrackId MP4FindTrackId(
|
|
1408 MP4FileHandle hFile,
|
|
1409 u_int16_t index,
|
|
1410 const char* type,
|
|
1411 u_int8_t subType)
|
|
1412 {
|
|
1413 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1414 try {
|
|
1415 return ((MP4File*)hFile)->FindTrackId(index, type, subType);
|
|
1416 }
|
|
1417 catch (MP4Error* e) {
|
|
1418 PRINT_ERROR(e);
|
|
1419 delete e;
|
|
1420 }
|
|
1421 }
|
|
1422 return MP4_INVALID_TRACK_ID;
|
|
1423 }
|
|
1424
|
|
1425 extern "C" u_int16_t MP4FindTrackIndex(
|
|
1426 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1427 {
|
|
1428 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1429 try {
|
|
1430 return ((MP4File*)hFile)->FindTrackIndex(trackId);
|
|
1431 }
|
|
1432 catch (MP4Error* e) {
|
|
1433 PRINT_ERROR(e);
|
|
1434 delete e;
|
|
1435 }
|
|
1436 }
|
|
1437 return (u_int16_t)-1;
|
|
1438 }
|
|
1439
|
|
1440 /* specific track properties */
|
|
1441
|
|
1442 extern "C" const char* MP4GetTrackType(
|
|
1443 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1444 {
|
|
1445 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1446 try {
|
|
1447 return ((MP4File*)hFile)->GetTrackType(trackId);
|
|
1448 }
|
|
1449 catch (MP4Error* e) {
|
|
1450 PRINT_ERROR(e);
|
|
1451 delete e;
|
|
1452 }
|
|
1453 }
|
|
1454 return NULL;
|
|
1455 }
|
|
1456 extern "C" const char* MP4GetTrackMediaDataName(
|
|
1457 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1458 {
|
|
1459 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1460 try {
|
|
1461 return ((MP4File*)hFile)->GetTrackMediaDataName(trackId);
|
|
1462 }
|
|
1463 catch (MP4Error* e) {
|
|
1464 PRINT_ERROR(e);
|
|
1465 delete e;
|
|
1466 }
|
|
1467 }
|
|
1468 return NULL;
|
|
1469 }
|
|
1470
|
|
1471
|
|
1472 extern "C" MP4Duration MP4GetTrackDuration(
|
|
1473 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1474 {
|
|
1475 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1476 try {
|
|
1477 return ((MP4File*)hFile)->GetTrackDuration(trackId);
|
|
1478 }
|
|
1479 catch (MP4Error* e) {
|
|
1480 PRINT_ERROR(e);
|
|
1481 delete e;
|
|
1482 }
|
|
1483 }
|
|
1484 return MP4_INVALID_DURATION;
|
|
1485 }
|
|
1486
|
|
1487 extern "C" u_int32_t MP4GetTrackTimeScale(
|
|
1488 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1489 {
|
|
1490 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1491 try {
|
|
1492 return ((MP4File*)hFile)->GetTrackTimeScale(trackId);
|
|
1493 }
|
|
1494 catch (MP4Error* e) {
|
|
1495 PRINT_ERROR(e);
|
|
1496 delete e;
|
|
1497 }
|
|
1498 }
|
|
1499 return 0;
|
|
1500 }
|
|
1501
|
|
1502 extern "C" bool MP4SetTrackTimeScale(
|
|
1503 MP4FileHandle hFile, MP4TrackId trackId, u_int32_t value)
|
|
1504 {
|
|
1505 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1506 try {
|
|
1507 ((MP4File*)hFile)->SetTrackTimeScale(trackId, value);
|
|
1508 return true;
|
|
1509 }
|
|
1510 catch (MP4Error* e) {
|
|
1511 PRINT_ERROR(e);
|
|
1512 delete e;
|
|
1513 }
|
|
1514 }
|
|
1515 return false;
|
|
1516 }
|
|
1517
|
|
1518 extern "C" u_int8_t MP4GetTrackAudioMpeg4Type(
|
|
1519 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1520 {
|
|
1521 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1522 try {
|
|
1523 return ((MP4File*)hFile)->GetTrackAudioMpeg4Type(trackId);
|
|
1524 }
|
|
1525 catch (MP4Error* e) {
|
|
1526 PRINT_ERROR(e);
|
|
1527 delete e;
|
|
1528 }
|
|
1529 }
|
|
1530 return MP4_MPEG4_INVALID_AUDIO_TYPE;
|
|
1531 }
|
|
1532
|
|
1533
|
|
1534
|
|
1535 // Replacement to MP4GetTrackVideoType and MP4GetTrackAudioType
|
|
1536 // Basically does the same thing but with a more self-explanatory name
|
|
1537 extern "C" u_int8_t MP4GetTrackEsdsObjectTypeId(
|
|
1538 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1539 {
|
|
1540 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1541 try {
|
|
1542
|
|
1543 return ((MP4File*)hFile)->GetTrackEsdsObjectTypeId(trackId);
|
|
1544 }
|
|
1545 catch (MP4Error* e) {
|
|
1546 PRINT_ERROR(e);
|
|
1547 delete e;
|
|
1548 }
|
|
1549 }
|
|
1550 return MP4_INVALID_AUDIO_TYPE;
|
|
1551 }
|
|
1552
|
|
1553 extern "C" MP4Duration MP4GetTrackFixedSampleDuration(
|
|
1554 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1555 {
|
|
1556 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1557 try {
|
|
1558 return ((MP4File*)hFile)->GetTrackFixedSampleDuration(trackId);
|
|
1559 }
|
|
1560 catch (MP4Error* e) {
|
|
1561 PRINT_ERROR(e);
|
|
1562 delete e;
|
|
1563 }
|
|
1564 }
|
|
1565 return MP4_INVALID_DURATION;
|
|
1566 }
|
|
1567
|
|
1568 extern "C" u_int32_t MP4GetTrackBitRate(
|
|
1569 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1570 {
|
|
1571 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1572 MP4File *pFile = (MP4File *)hFile;
|
|
1573 try {
|
|
1574 return pFile->GetTrackIntegerProperty(trackId,
|
|
1575 "mdia.minf.stbl.stsd.*.esds.decConfigDescr.avgBitrate");
|
|
1576 }
|
|
1577 catch (MP4Error* e) {
|
|
1578 PRINT_ERROR(e);
|
|
1579 delete e;
|
|
1580 }
|
|
1581 // if we're here, we can't get the bitrate from above -
|
|
1582 // lets calculate it
|
|
1583 try {
|
|
1584 MP4Duration trackDur;
|
|
1585 trackDur = MP4GetTrackDuration(hFile, trackId);
|
|
1586 uint64_t msDuration =
|
|
1587 pFile->ConvertFromTrackDuration(trackId, trackDur,
|
|
1588 MP4_MSECS_TIME_SCALE);
|
|
1589 MP4Track *pTrack = pFile->GetTrack(trackId);
|
|
1590 uint64_t bytes = pTrack->GetTotalOfSampleSizes();
|
|
1591 bytes *= (u_int64_t) (8 * 1000);
|
|
1592 bytes /= msDuration;
|
|
1593 return (uint32_t)bytes;
|
|
1594 }
|
|
1595 catch (MP4Error* e) {
|
|
1596 PRINT_ERROR(e);
|
|
1597 delete e;
|
|
1598 }
|
|
1599
|
|
1600 }
|
|
1601 return 0;
|
|
1602 }
|
|
1603
|
|
1604 extern "C" bool MP4GetTrackESConfiguration(
|
|
1605 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1606 u_int8_t** ppConfig, u_int32_t* pConfigSize)
|
|
1607 {
|
|
1608 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1609 try {
|
|
1610 ((MP4File*)hFile)->GetTrackESConfiguration(
|
|
1611 trackId, ppConfig, pConfigSize);
|
|
1612 return true;
|
|
1613 }
|
|
1614 catch (MP4Error* e) {
|
|
1615 PRINT_ERROR(e);
|
|
1616 delete e;
|
|
1617 }
|
|
1618 }
|
|
1619 *ppConfig = NULL;
|
|
1620 *pConfigSize = 0;
|
|
1621 return false;
|
|
1622 }
|
|
1623 extern "C" bool MP4GetTrackVideoMetadata(
|
|
1624 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1625 u_int8_t** ppConfig, u_int32_t* pConfigSize)
|
|
1626 {
|
|
1627 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1628 try {
|
|
1629 ((MP4File*)hFile)->GetTrackVideoMetadata(
|
|
1630 trackId, ppConfig, pConfigSize);
|
|
1631 return true;
|
|
1632 }
|
|
1633 catch (MP4Error* e) {
|
|
1634 PRINT_ERROR(e);
|
|
1635 delete e;
|
|
1636 }
|
|
1637 }
|
|
1638 *ppConfig = NULL;
|
|
1639 *pConfigSize = 0;
|
|
1640 return false;
|
|
1641 }
|
|
1642
|
|
1643 extern "C" bool MP4SetTrackESConfiguration(
|
|
1644 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1645 const u_int8_t* pConfig, u_int32_t configSize)
|
|
1646 {
|
|
1647 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1648 try {
|
|
1649 ((MP4File*)hFile)->SetTrackESConfiguration(
|
|
1650 trackId, pConfig, configSize);
|
|
1651 return true;
|
|
1652 }
|
|
1653 catch (MP4Error* e) {
|
|
1654 PRINT_ERROR(e);
|
|
1655 delete e;
|
|
1656 }
|
|
1657 }
|
|
1658 return false;
|
|
1659 }
|
|
1660
|
|
1661 extern "C" bool MP4GetTrackH264ProfileLevel (MP4FileHandle hFile,
|
|
1662 MP4TrackId trackId,
|
|
1663 uint8_t *pProfile,
|
|
1664 uint8_t *pLevel)
|
|
1665 {
|
|
1666 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1667 try {
|
|
1668 ((MP4File*)hFile)->GetTrackH264ProfileLevel(trackId, pProfile, pLevel);
|
|
1669 return true;
|
|
1670 }
|
|
1671 catch (MP4Error* e) {
|
|
1672 PRINT_ERROR(e);
|
|
1673 delete e;
|
|
1674 }
|
|
1675 }
|
|
1676 return false;
|
|
1677 }
|
|
1678 extern "C" bool MP4GetTrackH264SeqPictHeaders (MP4FileHandle hFile,
|
|
1679 MP4TrackId trackId,
|
|
1680 uint8_t ***pSeqHeader,
|
|
1681 uint32_t **pSeqHeaderSize,
|
|
1682 uint8_t ***pPictHeader,
|
|
1683 uint32_t **pPictHeaderSize)
|
|
1684 {
|
|
1685 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1686 try {
|
|
1687 ((MP4File*)hFile)->GetTrackH264SeqPictHeaders(trackId,
|
|
1688 pSeqHeader,
|
|
1689 pSeqHeaderSize,
|
|
1690 pPictHeader,
|
|
1691 pPictHeaderSize);
|
|
1692 return true;
|
|
1693 }
|
|
1694 catch (MP4Error* e) {
|
|
1695 PRINT_ERROR(e);
|
|
1696 delete e;
|
|
1697 }
|
|
1698 }
|
|
1699 return false;
|
|
1700 }
|
|
1701 extern "C" bool MP4GetTrackH264LengthSize (MP4FileHandle hFile,
|
|
1702 MP4TrackId trackId,
|
|
1703 uint32_t *pLength)
|
|
1704 {
|
|
1705 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1706 try {
|
|
1707 ((MP4File*)hFile)->GetTrackH264LengthSize(trackId,
|
|
1708 pLength);
|
|
1709 return true;
|
|
1710 }
|
|
1711 catch (MP4Error* e) {
|
|
1712 PRINT_ERROR(e);
|
|
1713 delete e;
|
|
1714 }
|
|
1715 }
|
|
1716 return false;
|
|
1717 }
|
|
1718
|
|
1719 extern "C" MP4SampleId MP4GetTrackNumberOfSamples(
|
|
1720 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1721 {
|
|
1722 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1723 try {
|
|
1724 return ((MP4File*)hFile)->GetTrackNumberOfSamples(trackId);
|
|
1725 }
|
|
1726 catch (MP4Error* e) {
|
|
1727 PRINT_ERROR(e);
|
|
1728 delete e;
|
|
1729 }
|
|
1730 }
|
|
1731 return 0;
|
|
1732 }
|
|
1733
|
|
1734 extern "C" u_int16_t MP4GetTrackVideoWidth(
|
|
1735 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1736 {
|
|
1737 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1738 try {
|
|
1739 return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
|
|
1740 "mdia.minf.stbl.stsd.*.width");
|
|
1741 }
|
|
1742 catch (MP4Error* e) {
|
|
1743 PRINT_ERROR(e);
|
|
1744 delete e;
|
|
1745 }
|
|
1746 }
|
|
1747 return 0;
|
|
1748 }
|
|
1749
|
|
1750 extern "C" u_int16_t MP4GetTrackVideoHeight(
|
|
1751 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1752 {
|
|
1753 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1754 try {
|
|
1755 return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
|
|
1756 "mdia.minf.stbl.stsd.*.height");
|
|
1757 }
|
|
1758 catch (MP4Error* e) {
|
|
1759 PRINT_ERROR(e);
|
|
1760 delete e;
|
|
1761 }
|
|
1762 }
|
|
1763 return 0;
|
|
1764 }
|
|
1765
|
|
1766 extern "C" double MP4GetTrackVideoFrameRate(
|
|
1767 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1768 {
|
|
1769 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1770 try {
|
|
1771 return ((MP4File*)hFile)->GetTrackVideoFrameRate(trackId);
|
|
1772 }
|
|
1773 catch (MP4Error* e) {
|
|
1774 PRINT_ERROR(e);
|
|
1775 delete e;
|
|
1776 }
|
|
1777 }
|
|
1778 return 0.0;
|
|
1779 }
|
|
1780
|
|
1781 extern "C" int MP4GetTrackAudioChannels (MP4FileHandle hFile,
|
|
1782 MP4TrackId trackId)
|
|
1783 {
|
|
1784 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1785 try {
|
|
1786 return ((MP4File*)hFile)->GetTrackAudioChannels(trackId);
|
|
1787 }
|
|
1788 catch (MP4Error* e) {
|
|
1789 PRINT_ERROR(e);
|
|
1790 delete e;
|
|
1791 }
|
|
1792 }
|
|
1793 return -1;
|
|
1794 }
|
|
1795
|
|
1796 // returns true if the track is a media track encrypted according to ismacryp
|
|
1797 extern "C" bool MP4IsIsmaCrypMediaTrack(
|
|
1798 MP4FileHandle hFile, MP4TrackId trackId)
|
|
1799 {
|
|
1800 bool retval = false;
|
|
1801 uint32_t verb = MP4GetVerbosity(hFile);
|
|
1802 MP4SetVerbosity(hFile, verb & ~(MP4_DETAILS_ERROR));
|
|
1803
|
|
1804 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1805 try {
|
|
1806 retval = ((MP4File*)hFile)->IsIsmaCrypMediaTrack(trackId);
|
|
1807 }
|
|
1808 catch (MP4Error* e) {
|
|
1809 PRINT_ERROR(e);
|
|
1810 delete e;
|
|
1811 }
|
|
1812 }
|
|
1813 MP4SetVerbosity(hFile, verb);
|
|
1814 return retval;
|
|
1815 }
|
|
1816
|
|
1817
|
|
1818 /* generic track properties */
|
|
1819
|
|
1820 extern "C" u_int64_t MP4GetTrackIntegerProperty (
|
|
1821 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1822 const char* propName)
|
|
1823 {
|
|
1824 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1825 try {
|
|
1826 return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
|
|
1827 propName);
|
|
1828 }
|
|
1829 catch (MP4Error* e) {
|
|
1830 PRINT_ERROR(e);
|
|
1831 delete e;
|
|
1832 }
|
|
1833 }
|
|
1834 return (u_int64_t)-1;
|
|
1835 }
|
|
1836 extern "C" bool MP4HaveTrackIntegerProperty(
|
|
1837 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1838 const char* propName)
|
|
1839 {
|
|
1840 // The same as MP4GetTrackIntegerProperty but with no error reporting
|
|
1841 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1842 try {
|
|
1843 return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
|
|
1844 propName) != (u_int64_t)-1;
|
|
1845 }
|
|
1846 catch (MP4Error* e) {
|
|
1847 // No error reporting
|
|
1848 delete e;
|
|
1849 }
|
|
1850 }
|
|
1851 return false;
|
|
1852 }
|
|
1853
|
|
1854 extern "C" float MP4GetTrackFloatProperty(
|
|
1855 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1856 const char* propName)
|
|
1857 {
|
|
1858 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1859 try {
|
|
1860 return ((MP4File*)hFile)->GetTrackFloatProperty(trackId, propName);
|
|
1861 }
|
|
1862 catch (MP4Error* e) {
|
|
1863 PRINT_ERROR(e);
|
|
1864 delete e;
|
|
1865 }
|
|
1866 }
|
|
1867 return NAN;
|
|
1868 }
|
|
1869
|
|
1870 extern "C" const char* MP4GetTrackStringProperty(
|
|
1871 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1872 const char* propName)
|
|
1873 {
|
|
1874 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1875 try {
|
|
1876 return ((MP4File*)hFile)->GetTrackStringProperty(trackId, propName);
|
|
1877 }
|
|
1878 catch (MP4Error* e) {
|
|
1879 PRINT_ERROR(e);
|
|
1880 delete e;
|
|
1881 }
|
|
1882 }
|
|
1883 return NULL;
|
|
1884 }
|
|
1885
|
|
1886 extern "C" void MP4GetTrackBytesProperty(
|
|
1887 MP4FileHandle hFile, MP4TrackId trackId, const char* propName,
|
|
1888 u_int8_t** ppValue, u_int32_t* pValueSize)
|
|
1889 {
|
|
1890 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1891 try {
|
|
1892 ((MP4File*)hFile)->GetTrackBytesProperty(
|
|
1893 trackId, propName, ppValue, pValueSize);
|
|
1894 return;
|
|
1895 }
|
|
1896 catch (MP4Error* e) {
|
|
1897 PRINT_ERROR(e);
|
|
1898 delete e;
|
|
1899 }
|
|
1900 }
|
|
1901 *ppValue = NULL;
|
|
1902 *pValueSize = 0;
|
|
1903 return;
|
|
1904 }
|
|
1905
|
|
1906 extern "C" bool MP4SetTrackIntegerProperty(
|
|
1907 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1908 const char* propName, int64_t value)
|
|
1909 {
|
|
1910 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1911 try {
|
|
1912 ((MP4File*)hFile)->SetTrackIntegerProperty(trackId,
|
|
1913 propName, value);
|
|
1914 return true;
|
|
1915 }
|
|
1916 catch (MP4Error* e) {
|
|
1917 PRINT_ERROR(e);
|
|
1918 delete e;
|
|
1919 }
|
|
1920 }
|
|
1921 return false;
|
|
1922 }
|
|
1923
|
|
1924 extern "C" bool MP4SetTrackFloatProperty(
|
|
1925 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1926 const char* propName, float value)
|
|
1927 {
|
|
1928 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1929 try {
|
|
1930 ((MP4File*)hFile)->SetTrackFloatProperty(trackId, propName, value);
|
|
1931 return true;
|
|
1932 }
|
|
1933 catch (MP4Error* e) {
|
|
1934 PRINT_ERROR(e);
|
|
1935 delete e;
|
|
1936 }
|
|
1937 }
|
|
1938 return false;
|
|
1939 }
|
|
1940
|
|
1941 extern "C" bool MP4SetTrackStringProperty(
|
|
1942 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1943 const char* propName, const char* value)
|
|
1944 {
|
|
1945 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1946 try {
|
|
1947 ((MP4File*)hFile)->SetTrackStringProperty(trackId, propName, value);
|
|
1948 return true;
|
|
1949 }
|
|
1950 catch (MP4Error* e) {
|
|
1951 PRINT_ERROR(e);
|
|
1952 delete e;
|
|
1953 }
|
|
1954 }
|
|
1955 return false;
|
|
1956 }
|
|
1957
|
|
1958 extern "C" bool MP4SetTrackBytesProperty(
|
|
1959 MP4FileHandle hFile, MP4TrackId trackId,
|
|
1960 const char* propName, const u_int8_t* pValue, u_int32_t valueSize)
|
|
1961 {
|
|
1962 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1963 try {
|
|
1964 ((MP4File*)hFile)->SetTrackBytesProperty(
|
|
1965 trackId, propName, pValue, valueSize);
|
|
1966 return true;
|
|
1967 }
|
|
1968 catch (MP4Error* e) {
|
|
1969 PRINT_ERROR(e);
|
|
1970 delete e;
|
|
1971 }
|
|
1972 }
|
|
1973 return false;
|
|
1974 }
|
|
1975
|
|
1976 /* sample operations */
|
|
1977
|
|
1978 extern "C" bool MP4ReadSample(
|
|
1979 /* input parameters */
|
|
1980 MP4FileHandle hFile,
|
|
1981 MP4TrackId trackId,
|
|
1982 MP4SampleId sampleId,
|
|
1983 /* output parameters */
|
|
1984 u_int8_t** ppBytes,
|
|
1985 u_int32_t* pNumBytes,
|
|
1986 MP4Timestamp* pStartTime,
|
|
1987 MP4Duration* pDuration,
|
|
1988 MP4Duration* pRenderingOffset,
|
|
1989 bool* pIsSyncSample)
|
|
1990 {
|
|
1991 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
1992 try {
|
|
1993 ((MP4File*)hFile)->ReadSample(
|
|
1994 trackId,
|
|
1995 sampleId,
|
|
1996 ppBytes,
|
|
1997 pNumBytes,
|
|
1998 pStartTime,
|
|
1999 pDuration,
|
|
2000 pRenderingOffset,
|
|
2001 pIsSyncSample);
|
|
2002 return true;
|
|
2003 }
|
|
2004 catch (MP4Error* e) {
|
|
2005 PRINT_ERROR(e);
|
|
2006 delete e;
|
|
2007 }
|
|
2008 }
|
|
2009 *pNumBytes = 0;
|
|
2010 return false;
|
|
2011 }
|
|
2012
|
|
2013 extern "C" bool MP4ReadSampleFromTime(
|
|
2014 /* input parameters */
|
|
2015 MP4FileHandle hFile,
|
|
2016 MP4TrackId trackId,
|
|
2017 MP4Timestamp when,
|
|
2018 /* output parameters */
|
|
2019 u_int8_t** ppBytes,
|
|
2020 u_int32_t* pNumBytes,
|
|
2021 MP4Timestamp* pStartTime,
|
|
2022 MP4Duration* pDuration,
|
|
2023 MP4Duration* pRenderingOffset,
|
|
2024 bool* pIsSyncSample)
|
|
2025 {
|
|
2026 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2027 try {
|
|
2028 MP4SampleId sampleId =
|
|
2029 ((MP4File*)hFile)->GetSampleIdFromTime(
|
|
2030 trackId, when, false);
|
|
2031
|
|
2032 ((MP4File*)hFile)->ReadSample(
|
|
2033 trackId,
|
|
2034 sampleId,
|
|
2035 ppBytes,
|
|
2036 pNumBytes,
|
|
2037 pStartTime,
|
|
2038 pDuration,
|
|
2039 pRenderingOffset,
|
|
2040 pIsSyncSample);
|
|
2041
|
|
2042 return true;
|
|
2043 }
|
|
2044 catch (MP4Error* e) {
|
|
2045 PRINT_ERROR(e);
|
|
2046 delete e;
|
|
2047 }
|
|
2048 }
|
|
2049 *pNumBytes = 0;
|
|
2050 return false;
|
|
2051 }
|
|
2052
|
|
2053 extern "C" bool MP4WriteSample(
|
|
2054 MP4FileHandle hFile,
|
|
2055 MP4TrackId trackId,
|
|
2056 const u_int8_t* pBytes,
|
|
2057 u_int32_t numBytes,
|
|
2058 MP4Duration duration,
|
|
2059 MP4Duration renderingOffset,
|
|
2060 bool isSyncSample)
|
|
2061 {
|
|
2062 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2063 try {
|
|
2064 ((MP4File*)hFile)->WriteSample(
|
|
2065 trackId,
|
|
2066 pBytes,
|
|
2067 numBytes,
|
|
2068 duration,
|
|
2069 renderingOffset,
|
|
2070 isSyncSample);
|
|
2071 return true;
|
|
2072 }
|
|
2073 catch (MP4Error* e) {
|
|
2074 PRINT_ERROR(e);
|
|
2075 delete e;
|
|
2076 }
|
|
2077 }
|
|
2078 return false;
|
|
2079 }
|
|
2080
|
|
2081 extern "C" bool MP4CopySample(
|
|
2082 MP4FileHandle srcFile,
|
|
2083 MP4TrackId srcTrackId,
|
|
2084 MP4SampleId srcSampleId,
|
|
2085 MP4FileHandle dstFile,
|
|
2086 MP4TrackId dstTrackId,
|
|
2087 MP4Duration dstSampleDuration)
|
|
2088 {
|
|
2089 bool rc;
|
|
2090 u_int8_t* pBytes = NULL;
|
|
2091 u_int32_t numBytes = 0;
|
|
2092 MP4Duration sampleDuration;
|
|
2093 MP4Duration renderingOffset;
|
|
2094 bool isSyncSample;
|
|
2095
|
|
2096 // Note: we leave it up to the caller to ensure that the
|
|
2097 // source and destination tracks are compatible.
|
|
2098 // i.e. copying audio samples into a video track
|
|
2099 // is unlikely to do anything useful
|
|
2100
|
|
2101 rc = MP4ReadSample(
|
|
2102 srcFile,
|
|
2103 srcTrackId,
|
|
2104 srcSampleId,
|
|
2105 &pBytes,
|
|
2106 &numBytes,
|
|
2107 NULL,
|
|
2108 &sampleDuration,
|
|
2109 &renderingOffset,
|
|
2110 &isSyncSample);
|
|
2111
|
|
2112 if (!rc) {
|
|
2113 return false;
|
|
2114 }
|
|
2115
|
|
2116 if (dstFile == MP4_INVALID_FILE_HANDLE) {
|
|
2117 dstFile = srcFile;
|
|
2118 }
|
|
2119 if (dstTrackId == MP4_INVALID_TRACK_ID) {
|
|
2120 dstTrackId = srcTrackId;
|
|
2121 }
|
|
2122 if (dstSampleDuration != MP4_INVALID_DURATION) {
|
|
2123 sampleDuration = dstSampleDuration;
|
|
2124 }
|
|
2125
|
|
2126 rc = MP4WriteSample(
|
|
2127 dstFile,
|
|
2128 dstTrackId,
|
|
2129 pBytes,
|
|
2130 numBytes,
|
|
2131 sampleDuration,
|
|
2132 renderingOffset,
|
|
2133 isSyncSample);
|
|
2134
|
|
2135 free(pBytes);
|
|
2136
|
|
2137 return rc;
|
|
2138 }
|
|
2139
|
|
2140 extern "C" bool MP4EncAndCopySample(
|
|
2141 MP4FileHandle srcFile,
|
|
2142 MP4TrackId srcTrackId,
|
|
2143 MP4SampleId srcSampleId,
|
|
2144 encryptFunc_t encfcnp,
|
|
2145 u_int32_t encfcnparam1,
|
|
2146 MP4FileHandle dstFile,
|
|
2147 MP4TrackId dstTrackId,
|
|
2148 MP4Duration dstSampleDuration)
|
|
2149 {
|
|
2150 bool rc;
|
|
2151 u_int8_t* pBytes = NULL;
|
|
2152 u_int32_t numBytes = 0;
|
|
2153 u_int8_t* encSampleData = NULL;
|
|
2154 u_int32_t encSampleLength = 0;
|
|
2155 MP4Duration sampleDuration;
|
|
2156 MP4Duration renderingOffset;
|
|
2157 bool isSyncSample;
|
|
2158
|
|
2159 // Note: we leave it up to the caller to ensure that the
|
|
2160 // source and destination tracks are compatible.
|
|
2161 // i.e. copying audio samples into a video track
|
|
2162 // is unlikely to do anything useful
|
|
2163
|
|
2164 rc = MP4ReadSample(
|
|
2165 srcFile,
|
|
2166 srcTrackId,
|
|
2167 srcSampleId,
|
|
2168 &pBytes,
|
|
2169 &numBytes,
|
|
2170 NULL,
|
|
2171 &sampleDuration,
|
|
2172 &renderingOffset,
|
|
2173 &isSyncSample);
|
|
2174
|
|
2175 if (!rc) {
|
|
2176 return false;
|
|
2177 }
|
|
2178
|
|
2179 if (dstFile == MP4_INVALID_FILE_HANDLE) {
|
|
2180 dstFile = srcFile;
|
|
2181 }
|
|
2182 if (dstTrackId == MP4_INVALID_TRACK_ID) {
|
|
2183 dstTrackId = srcTrackId;
|
|
2184 }
|
|
2185 if (dstSampleDuration != MP4_INVALID_DURATION) {
|
|
2186 sampleDuration = dstSampleDuration;
|
|
2187 }
|
|
2188
|
|
2189 //if (ismacrypEncryptSampleAddHeader(ismaCryptSId, numBytes, pBytes,
|
|
2190 // &encSampleLength, &encSampleData) != 0) {
|
|
2191 if (encfcnp(encfcnparam1, numBytes, pBytes,
|
|
2192 &encSampleLength, &encSampleData) != 0) {
|
|
2193 fprintf(stderr,
|
|
2194 "Can't encrypt the sample and add its header %u\n",
|
|
2195 srcSampleId);
|
|
2196 }
|
|
2197
|
|
2198 rc = MP4WriteSample(
|
|
2199 dstFile,
|
|
2200 dstTrackId,
|
|
2201 encSampleData,
|
|
2202 encSampleLength,
|
|
2203 sampleDuration,
|
|
2204 renderingOffset,
|
|
2205 isSyncSample);
|
|
2206
|
|
2207 free(pBytes);
|
|
2208
|
|
2209 if (encSampleData != NULL) {
|
|
2210 free(encSampleData);
|
|
2211 }
|
|
2212
|
|
2213 return rc;
|
|
2214 }
|
|
2215
|
|
2216 extern "C" bool MP4ReferenceSample(
|
|
2217 MP4FileHandle srcFile,
|
|
2218 MP4TrackId srcTrackId,
|
|
2219 MP4SampleId srcSampleId,
|
|
2220 MP4FileHandle dstFile,
|
|
2221 MP4TrackId dstTrackId,
|
|
2222 MP4Duration dstSampleDuration)
|
|
2223 {
|
|
2224 // LATER Not yet implemented
|
|
2225 return false;
|
|
2226 }
|
|
2227
|
|
2228 extern "C" u_int32_t MP4GetSampleSize(
|
|
2229 MP4FileHandle hFile,
|
|
2230 MP4TrackId trackId,
|
|
2231 MP4SampleId sampleId)
|
|
2232 {
|
|
2233 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2234 try {
|
|
2235 return ((MP4File*)hFile)->GetSampleSize(
|
|
2236 trackId, sampleId);
|
|
2237 }
|
|
2238 catch (MP4Error* e) {
|
|
2239 PRINT_ERROR(e);
|
|
2240 delete e;
|
|
2241 }
|
|
2242 }
|
|
2243 return 0;
|
|
2244 }
|
|
2245
|
|
2246 extern "C" u_int32_t MP4GetTrackMaxSampleSize(
|
|
2247 MP4FileHandle hFile,
|
|
2248 MP4TrackId trackId)
|
|
2249 {
|
|
2250 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2251 try {
|
|
2252 return ((MP4File*)hFile)->GetTrackMaxSampleSize(trackId);
|
|
2253 }
|
|
2254 catch (MP4Error* e) {
|
|
2255 PRINT_ERROR(e);
|
|
2256 delete e;
|
|
2257 }
|
|
2258 }
|
|
2259 return 0;
|
|
2260 }
|
|
2261
|
|
2262 extern "C" MP4SampleId MP4GetSampleIdFromTime(
|
|
2263 MP4FileHandle hFile,
|
|
2264 MP4TrackId trackId,
|
|
2265 MP4Timestamp when,
|
|
2266 bool wantSyncSample)
|
|
2267 {
|
|
2268 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2269 try {
|
|
2270 return ((MP4File*)hFile)->GetSampleIdFromTime(
|
|
2271 trackId, when, wantSyncSample);
|
|
2272 }
|
|
2273 catch (MP4Error* e) {
|
|
2274 PRINT_ERROR(e);
|
|
2275 delete e;
|
|
2276 }
|
|
2277 }
|
|
2278 return MP4_INVALID_SAMPLE_ID;
|
|
2279 }
|
|
2280
|
|
2281 extern "C" MP4Timestamp MP4GetSampleTime(
|
|
2282 MP4FileHandle hFile,
|
|
2283 MP4TrackId trackId,
|
|
2284 MP4SampleId sampleId)
|
|
2285 {
|
|
2286 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2287 try {
|
|
2288 return ((MP4File*)hFile)->GetSampleTime(
|
|
2289 trackId, sampleId);
|
|
2290 }
|
|
2291 catch (MP4Error* e) {
|
|
2292 PRINT_ERROR(e);
|
|
2293 delete e;
|
|
2294 }
|
|
2295 }
|
|
2296 return MP4_INVALID_TIMESTAMP;
|
|
2297 }
|
|
2298
|
|
2299 extern "C" MP4Duration MP4GetSampleDuration(
|
|
2300 MP4FileHandle hFile,
|
|
2301 MP4TrackId trackId,
|
|
2302 MP4SampleId sampleId)
|
|
2303 {
|
|
2304 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2305 try {
|
|
2306 return ((MP4File*)hFile)->GetSampleDuration(
|
|
2307 trackId, sampleId);
|
|
2308 }
|
|
2309 catch (MP4Error* e) {
|
|
2310 PRINT_ERROR(e);
|
|
2311 delete e;
|
|
2312 }
|
|
2313 }
|
|
2314 return MP4_INVALID_DURATION;
|
|
2315 }
|
|
2316
|
|
2317 extern "C" MP4Duration MP4GetSampleRenderingOffset(
|
|
2318 MP4FileHandle hFile,
|
|
2319 MP4TrackId trackId,
|
|
2320 MP4SampleId sampleId)
|
|
2321 {
|
|
2322 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2323 try {
|
|
2324 return ((MP4File*)hFile)->GetSampleRenderingOffset(
|
|
2325 trackId, sampleId);
|
|
2326 }
|
|
2327 catch (MP4Error* e) {
|
|
2328 PRINT_ERROR(e);
|
|
2329 delete e;
|
|
2330 }
|
|
2331 }
|
|
2332 return MP4_INVALID_DURATION;
|
|
2333 }
|
|
2334
|
|
2335 extern "C" bool MP4SetSampleRenderingOffset(
|
|
2336 MP4FileHandle hFile,
|
|
2337 MP4TrackId trackId,
|
|
2338 MP4SampleId sampleId,
|
|
2339 MP4Duration renderingOffset)
|
|
2340 {
|
|
2341 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2342 try {
|
|
2343 ((MP4File*)hFile)->SetSampleRenderingOffset(
|
|
2344 trackId, sampleId, renderingOffset);
|
|
2345 return true;
|
|
2346 }
|
|
2347 catch (MP4Error* e) {
|
|
2348 PRINT_ERROR(e);
|
|
2349 delete e;
|
|
2350 }
|
|
2351 }
|
|
2352 return false;
|
|
2353 }
|
|
2354
|
|
2355 extern "C" int8_t MP4GetSampleSync(
|
|
2356 MP4FileHandle hFile,
|
|
2357 MP4TrackId trackId,
|
|
2358 MP4SampleId sampleId)
|
|
2359 {
|
|
2360 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2361 try {
|
|
2362 return ((MP4File*)hFile)->GetSampleSync(
|
|
2363 trackId, sampleId);
|
|
2364 }
|
|
2365 catch (MP4Error* e) {
|
|
2366 PRINT_ERROR(e);
|
|
2367 delete e;
|
|
2368 }
|
|
2369 }
|
|
2370 return -1;
|
|
2371 }
|
|
2372
|
|
2373
|
|
2374 extern "C" u_int64_t MP4ConvertFromMovieDuration(
|
|
2375 MP4FileHandle hFile,
|
|
2376 MP4Duration duration,
|
|
2377 u_int32_t timeScale)
|
|
2378 {
|
|
2379 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2380 try {
|
|
2381 return ((MP4File*)hFile)->ConvertFromMovieDuration(
|
|
2382 duration, timeScale);
|
|
2383 }
|
|
2384 catch (MP4Error* e) {
|
|
2385 PRINT_ERROR(e);
|
|
2386 delete e;
|
|
2387 }
|
|
2388 }
|
|
2389 return (u_int64_t)MP4_INVALID_DURATION;
|
|
2390 }
|
|
2391
|
|
2392 extern "C" u_int64_t MP4ConvertFromTrackTimestamp(
|
|
2393 MP4FileHandle hFile,
|
|
2394 MP4TrackId trackId,
|
|
2395 MP4Timestamp timeStamp,
|
|
2396 u_int32_t timeScale)
|
|
2397 {
|
|
2398 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2399 try {
|
|
2400 return ((MP4File*)hFile)->ConvertFromTrackTimestamp(
|
|
2401 trackId, timeStamp, timeScale);
|
|
2402 }
|
|
2403 catch (MP4Error* e) {
|
|
2404 PRINT_ERROR(e);
|
|
2405 delete e;
|
|
2406 }
|
|
2407 }
|
|
2408 return (u_int64_t)MP4_INVALID_TIMESTAMP;
|
|
2409 }
|
|
2410
|
|
2411 extern "C" MP4Timestamp MP4ConvertToTrackTimestamp(
|
|
2412 MP4FileHandle hFile,
|
|
2413 MP4TrackId trackId,
|
|
2414 u_int64_t timeStamp,
|
|
2415 u_int32_t timeScale)
|
|
2416 {
|
|
2417 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2418 try {
|
|
2419 return ((MP4File*)hFile)->ConvertToTrackTimestamp(
|
|
2420 trackId, timeStamp, timeScale);
|
|
2421 }
|
|
2422 catch (MP4Error* e) {
|
|
2423 PRINT_ERROR(e);
|
|
2424 delete e;
|
|
2425 }
|
|
2426 }
|
|
2427 return MP4_INVALID_TIMESTAMP;
|
|
2428 }
|
|
2429
|
|
2430 extern "C" u_int64_t MP4ConvertFromTrackDuration(
|
|
2431 MP4FileHandle hFile,
|
|
2432 MP4TrackId trackId,
|
|
2433 MP4Duration duration,
|
|
2434 u_int32_t timeScale)
|
|
2435 {
|
|
2436 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2437 try {
|
|
2438 return ((MP4File*)hFile)->ConvertFromTrackDuration(
|
|
2439 trackId, duration, timeScale);
|
|
2440 }
|
|
2441 catch (MP4Error* e) {
|
|
2442 PRINT_ERROR(e);
|
|
2443 delete e;
|
|
2444 }
|
|
2445 }
|
|
2446 return (u_int64_t)MP4_INVALID_DURATION;
|
|
2447 }
|
|
2448
|
|
2449 extern "C" MP4Duration MP4ConvertToTrackDuration(
|
|
2450 MP4FileHandle hFile,
|
|
2451 MP4TrackId trackId,
|
|
2452 u_int64_t duration,
|
|
2453 u_int32_t timeScale)
|
|
2454 {
|
|
2455 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2456 try {
|
|
2457 return ((MP4File*)hFile)->ConvertToTrackDuration(
|
|
2458 trackId, duration, timeScale);
|
|
2459 }
|
|
2460 catch (MP4Error* e) {
|
|
2461 PRINT_ERROR(e);
|
|
2462 delete e;
|
|
2463 }
|
|
2464 }
|
|
2465 return MP4_INVALID_DURATION;
|
|
2466 }
|
|
2467
|
|
2468 extern "C" bool MP4GetHintTrackRtpPayload(
|
|
2469 MP4FileHandle hFile,
|
|
2470 MP4TrackId hintTrackId,
|
|
2471 char** ppPayloadName,
|
|
2472 u_int8_t* pPayloadNumber,
|
|
2473 u_int16_t* pMaxPayloadSize,
|
|
2474 char **ppEncodingParams)
|
|
2475 {
|
|
2476 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2477 try {
|
|
2478 ((MP4File*)hFile)->GetHintTrackRtpPayload(
|
|
2479 hintTrackId, ppPayloadName, pPayloadNumber, pMaxPayloadSize,
|
|
2480 ppEncodingParams);
|
|
2481 return true;
|
|
2482 }
|
|
2483 catch (MP4Error* e) {
|
|
2484 PRINT_ERROR(e);
|
|
2485 delete e;
|
|
2486 }
|
|
2487 }
|
|
2488 return false;
|
|
2489 }
|
|
2490
|
|
2491 extern "C" bool MP4SetHintTrackRtpPayload(
|
|
2492 MP4FileHandle hFile,
|
|
2493 MP4TrackId hintTrackId,
|
|
2494 const char* pPayloadName,
|
|
2495 u_int8_t* pPayloadNumber,
|
|
2496 u_int16_t maxPayloadSize,
|
|
2497 const char *encode_params,
|
|
2498 bool include_rtp_map,
|
|
2499 bool include_mpeg4_esid)
|
|
2500 {
|
|
2501 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2502 try {
|
|
2503 ((MP4File*)hFile)->SetHintTrackRtpPayload(
|
|
2504 hintTrackId, pPayloadName, pPayloadNumber, maxPayloadSize, encode_params,
|
|
2505 include_rtp_map, include_mpeg4_esid);
|
|
2506 return true;
|
|
2507 }
|
|
2508 catch (MP4Error* e) {
|
|
2509 PRINT_ERROR(e);
|
|
2510 delete e;
|
|
2511 }
|
|
2512 }
|
|
2513 return false;
|
|
2514 }
|
|
2515
|
|
2516 extern "C" const char* MP4GetSessionSdp(
|
|
2517 MP4FileHandle hFile)
|
|
2518 {
|
|
2519 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2520 try {
|
|
2521 return ((MP4File*)hFile)->GetSessionSdp();
|
|
2522 }
|
|
2523 catch (MP4Error* e) {
|
|
2524 PRINT_ERROR(e);
|
|
2525 delete e;
|
|
2526 }
|
|
2527 }
|
|
2528 return NULL;
|
|
2529 }
|
|
2530
|
|
2531 extern "C" bool MP4SetSessionSdp(
|
|
2532 MP4FileHandle hFile,
|
|
2533 const char* sdpString)
|
|
2534 {
|
|
2535 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2536 try {
|
|
2537 ((MP4File*)hFile)->SetSessionSdp(sdpString);
|
|
2538 return true;
|
|
2539 }
|
|
2540 catch (MP4Error* e) {
|
|
2541 PRINT_ERROR(e);
|
|
2542 delete e;
|
|
2543 }
|
|
2544 }
|
|
2545 return false;
|
|
2546 }
|
|
2547
|
|
2548 extern "C" bool MP4AppendSessionSdp(
|
|
2549 MP4FileHandle hFile,
|
|
2550 const char* sdpString)
|
|
2551 {
|
|
2552 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2553 try {
|
|
2554 ((MP4File*)hFile)->AppendSessionSdp(sdpString);
|
|
2555 return true;
|
|
2556 }
|
|
2557 catch (MP4Error* e) {
|
|
2558 PRINT_ERROR(e);
|
|
2559 delete e;
|
|
2560 }
|
|
2561 }
|
|
2562 return false;
|
|
2563 }
|
|
2564
|
|
2565 extern "C" const char* MP4GetHintTrackSdp(
|
|
2566 MP4FileHandle hFile,
|
|
2567 MP4TrackId hintTrackId)
|
|
2568 {
|
|
2569 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2570 try {
|
|
2571 return ((MP4File*)hFile)->GetHintTrackSdp(hintTrackId);
|
|
2572 }
|
|
2573 catch (MP4Error* e) {
|
|
2574 PRINT_ERROR(e);
|
|
2575 delete e;
|
|
2576 }
|
|
2577 }
|
|
2578 return NULL;
|
|
2579 }
|
|
2580
|
|
2581 extern "C" bool MP4SetHintTrackSdp(
|
|
2582 MP4FileHandle hFile,
|
|
2583 MP4TrackId hintTrackId,
|
|
2584 const char* sdpString)
|
|
2585 {
|
|
2586 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2587 try {
|
|
2588 ((MP4File*)hFile)->SetHintTrackSdp(hintTrackId, sdpString);
|
|
2589 return true;
|
|
2590 }
|
|
2591 catch (MP4Error* e) {
|
|
2592 PRINT_ERROR(e);
|
|
2593 delete e;
|
|
2594 }
|
|
2595 }
|
|
2596 return false;
|
|
2597 }
|
|
2598
|
|
2599 extern "C" bool MP4AppendHintTrackSdp(
|
|
2600 MP4FileHandle hFile,
|
|
2601 MP4TrackId hintTrackId,
|
|
2602 const char* sdpString)
|
|
2603 {
|
|
2604 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2605 try {
|
|
2606 ((MP4File*)hFile)->AppendHintTrackSdp(hintTrackId, sdpString);
|
|
2607 return true;
|
|
2608 }
|
|
2609 catch (MP4Error* e) {
|
|
2610 PRINT_ERROR(e);
|
|
2611 delete e;
|
|
2612 }
|
|
2613 }
|
|
2614 return false;
|
|
2615 }
|
|
2616
|
|
2617 extern "C" MP4TrackId MP4GetHintTrackReferenceTrackId(
|
|
2618 MP4FileHandle hFile,
|
|
2619 MP4TrackId hintTrackId)
|
|
2620 {
|
|
2621 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2622 try {
|
|
2623 return ((MP4File*)hFile)->
|
|
2624 GetHintTrackReferenceTrackId(hintTrackId);
|
|
2625 }
|
|
2626 catch (MP4Error* e) {
|
|
2627 PRINT_ERROR(e);
|
|
2628 delete e;
|
|
2629 }
|
|
2630 }
|
|
2631 return MP4_INVALID_TRACK_ID;
|
|
2632 }
|
|
2633
|
|
2634 extern "C" bool MP4ReadRtpHint(
|
|
2635 MP4FileHandle hFile,
|
|
2636 MP4TrackId hintTrackId,
|
|
2637 MP4SampleId hintSampleId,
|
|
2638 u_int16_t* pNumPackets)
|
|
2639 {
|
|
2640 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2641 try {
|
|
2642 ((MP4File*)hFile)->ReadRtpHint(
|
|
2643 hintTrackId, hintSampleId, pNumPackets);
|
|
2644 return true;
|
|
2645 }
|
|
2646 catch (MP4Error* e) {
|
|
2647 PRINT_ERROR(e);
|
|
2648 delete e;
|
|
2649 }
|
|
2650 }
|
|
2651 return false;
|
|
2652 }
|
|
2653
|
|
2654 extern "C" u_int16_t MP4GetRtpHintNumberOfPackets(
|
|
2655 MP4FileHandle hFile,
|
|
2656 MP4TrackId hintTrackId)
|
|
2657 {
|
|
2658 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2659 try {
|
|
2660 return ((MP4File*)hFile)->GetRtpHintNumberOfPackets(hintTrackId);
|
|
2661 }
|
|
2662 catch (MP4Error* e) {
|
|
2663 PRINT_ERROR(e);
|
|
2664 delete e;
|
|
2665 }
|
|
2666 }
|
|
2667 return 0;
|
|
2668 }
|
|
2669
|
|
2670 extern "C" int8_t MP4GetRtpPacketBFrame(
|
|
2671 MP4FileHandle hFile,
|
|
2672 MP4TrackId hintTrackId,
|
|
2673 u_int16_t packetIndex)
|
|
2674 {
|
|
2675 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2676 try {
|
|
2677 return ((MP4File*)hFile)->
|
|
2678 GetRtpPacketBFrame(hintTrackId, packetIndex);
|
|
2679 }
|
|
2680 catch (MP4Error* e) {
|
|
2681 PRINT_ERROR(e);
|
|
2682 delete e;
|
|
2683 }
|
|
2684 }
|
|
2685 return -1;
|
|
2686 }
|
|
2687
|
|
2688 extern "C" int32_t MP4GetRtpPacketTransmitOffset(
|
|
2689 MP4FileHandle hFile,
|
|
2690 MP4TrackId hintTrackId,
|
|
2691 u_int16_t packetIndex)
|
|
2692 {
|
|
2693 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2694 try {
|
|
2695 return ((MP4File*)hFile)->
|
|
2696 GetRtpPacketTransmitOffset(hintTrackId, packetIndex);
|
|
2697 }
|
|
2698 catch (MP4Error* e) {
|
|
2699 PRINT_ERROR(e);
|
|
2700 delete e;
|
|
2701 }
|
|
2702 }
|
|
2703 return 0;
|
|
2704 }
|
|
2705
|
|
2706 extern "C" bool MP4ReadRtpPacket(
|
|
2707 MP4FileHandle hFile,
|
|
2708 MP4TrackId hintTrackId,
|
|
2709 u_int16_t packetIndex,
|
|
2710 u_int8_t** ppBytes,
|
|
2711 u_int32_t* pNumBytes,
|
|
2712 u_int32_t ssrc,
|
|
2713 bool includeHeader,
|
|
2714 bool includePayload)
|
|
2715 {
|
|
2716 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2717 try {
|
|
2718 ((MP4File*)hFile)->ReadRtpPacket(
|
|
2719 hintTrackId, packetIndex,
|
|
2720 ppBytes, pNumBytes,
|
|
2721 ssrc, includeHeader, includePayload);
|
|
2722 return true;
|
|
2723 }
|
|
2724 catch (MP4Error* e) {
|
|
2725 PRINT_ERROR(e);
|
|
2726 delete e;
|
|
2727 }
|
|
2728 }
|
|
2729 return false;
|
|
2730 }
|
|
2731
|
|
2732 extern "C" MP4Timestamp MP4GetRtpTimestampStart(
|
|
2733 MP4FileHandle hFile,
|
|
2734 MP4TrackId hintTrackId)
|
|
2735 {
|
|
2736 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2737 try {
|
|
2738 return ((MP4File*)hFile)->GetRtpTimestampStart(hintTrackId);
|
|
2739 }
|
|
2740 catch (MP4Error* e) {
|
|
2741 PRINT_ERROR(e);
|
|
2742 delete e;
|
|
2743 }
|
|
2744 }
|
|
2745 return MP4_INVALID_TIMESTAMP;
|
|
2746 }
|
|
2747
|
|
2748 extern "C" bool MP4SetRtpTimestampStart(
|
|
2749 MP4FileHandle hFile,
|
|
2750 MP4TrackId hintTrackId,
|
|
2751 MP4Timestamp rtpStart)
|
|
2752 {
|
|
2753 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2754 try {
|
|
2755 ((MP4File*)hFile)->SetRtpTimestampStart(
|
|
2756 hintTrackId, rtpStart);
|
|
2757 return true;
|
|
2758 }
|
|
2759 catch (MP4Error* e) {
|
|
2760 PRINT_ERROR(e);
|
|
2761 delete e;
|
|
2762 }
|
|
2763 }
|
|
2764 return false;
|
|
2765 }
|
|
2766
|
|
2767 extern "C" bool MP4AddRtpHint(
|
|
2768 MP4FileHandle hFile,
|
|
2769 MP4TrackId hintTrackId)
|
|
2770 {
|
|
2771 return MP4AddRtpVideoHint(hFile, hintTrackId, false, 0);
|
|
2772 }
|
|
2773
|
|
2774 extern "C" bool MP4AddRtpVideoHint(
|
|
2775 MP4FileHandle hFile,
|
|
2776 MP4TrackId hintTrackId,
|
|
2777 bool isBframe,
|
|
2778 u_int32_t timestampOffset)
|
|
2779 {
|
|
2780 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2781 try {
|
|
2782 ((MP4File*)hFile)->AddRtpHint(hintTrackId,
|
|
2783 isBframe, timestampOffset);
|
|
2784 return true;
|
|
2785 }
|
|
2786 catch (MP4Error* e) {
|
|
2787 PRINT_ERROR(e);
|
|
2788 delete e;
|
|
2789 }
|
|
2790 }
|
|
2791 return false;
|
|
2792 }
|
|
2793
|
|
2794 extern "C" bool MP4AddRtpPacket(
|
|
2795 MP4FileHandle hFile,
|
|
2796 MP4TrackId hintTrackId,
|
|
2797 bool setMbit,
|
|
2798 int32_t transmitOffset)
|
|
2799 {
|
|
2800 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2801 try {
|
|
2802 ((MP4File*)hFile)->AddRtpPacket(
|
|
2803 hintTrackId, setMbit, transmitOffset);
|
|
2804 return true;
|
|
2805 }
|
|
2806 catch (MP4Error* e) {
|
|
2807 PRINT_ERROR(e);
|
|
2808 delete e;
|
|
2809 }
|
|
2810 }
|
|
2811 return false;
|
|
2812 }
|
|
2813
|
|
2814 extern "C" bool MP4AddRtpImmediateData(
|
|
2815 MP4FileHandle hFile,
|
|
2816 MP4TrackId hintTrackId,
|
|
2817 const u_int8_t* pBytes,
|
|
2818 u_int32_t numBytes)
|
|
2819 {
|
|
2820 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2821 try {
|
|
2822 ((MP4File*)hFile)->AddRtpImmediateData(hintTrackId,
|
|
2823 pBytes, numBytes);
|
|
2824 return true;
|
|
2825 }
|
|
2826 catch (MP4Error* e) {
|
|
2827 PRINT_ERROR(e);
|
|
2828 delete e;
|
|
2829 }
|
|
2830 }
|
|
2831 return false;
|
|
2832 }
|
|
2833
|
|
2834 extern "C" bool MP4AddRtpSampleData(
|
|
2835 MP4FileHandle hFile,
|
|
2836 MP4TrackId hintTrackId,
|
|
2837 MP4SampleId sampleId,
|
|
2838 u_int32_t dataOffset,
|
|
2839 u_int32_t dataLength)
|
|
2840 {
|
|
2841 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2842 try {
|
|
2843 ((MP4File*)hFile)->AddRtpSampleData(
|
|
2844 hintTrackId, sampleId, dataOffset, dataLength);
|
|
2845 return true;
|
|
2846 }
|
|
2847 catch (MP4Error* e) {
|
|
2848 PRINT_ERROR(e);
|
|
2849 delete e;
|
|
2850 }
|
|
2851 }
|
|
2852 return false;
|
|
2853 }
|
|
2854
|
|
2855 extern "C" bool MP4AddRtpESConfigurationPacket(
|
|
2856 MP4FileHandle hFile,
|
|
2857 MP4TrackId hintTrackId)
|
|
2858 {
|
|
2859 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2860 try {
|
|
2861 ((MP4File*)hFile)->AddRtpESConfigurationPacket(hintTrackId);
|
|
2862 return true;
|
|
2863 }
|
|
2864 catch (MP4Error* e) {
|
|
2865 PRINT_ERROR(e);
|
|
2866 delete e;
|
|
2867 }
|
|
2868 }
|
|
2869 return false;
|
|
2870 }
|
|
2871
|
|
2872 extern "C" bool MP4WriteRtpHint(
|
|
2873 MP4FileHandle hFile,
|
|
2874 MP4TrackId hintTrackId,
|
|
2875 MP4Duration duration,
|
|
2876 bool isSyncSample)
|
|
2877 {
|
|
2878 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
2879 try {
|
|
2880 ((MP4File*)hFile)->WriteRtpHint(
|
|
2881 hintTrackId, duration, isSyncSample);
|
|
2882 return true;
|
|
2883 }
|
|
2884 catch (MP4Error* e) {
|
|
2885 PRINT_ERROR(e);
|
|
2886 delete e;
|
|
2887 }
|
|
2888 }
|
|
2889 return false;
|
|
2890 }
|
|
2891 /* 3GPP specific operations */
|
|
2892
|
|
2893 extern "C" bool MP4Make3GPCompliant(
|
|
2894 const char* fileName,
|
|
2895 u_int32_t verbosity,
|
|
2896 char* majorBrand,
|
|
2897 u_int32_t minorVersion,
|
|
2898 char** supportedBrands,
|
|
2899 u_int32_t supportedBrandsCount,
|
|
2900 bool deleteIodsAtom)
|
|
2901 {
|
|
2902 MP4File* pFile = NULL;
|
|
2903
|
|
2904 try {
|
|
2905 pFile = new MP4File(verbosity);
|
|
2906 pFile->Modify(fileName);
|
|
2907 pFile->Make3GPCompliant(fileName, majorBrand, minorVersion, supportedBrands, supportedBrandsCount, deleteIodsAtom);
|
|
2908 pFile->Close();
|
|
2909 delete pFile;
|
|
2910 return true;
|
|
2911 }
|
|
2912 catch (MP4Error* e) {
|
|
2913 VERBOSE_ERROR(verbosity, e->Print());
|
|
2914 delete e;
|
|
2915 }
|
|
2916 delete pFile;
|
|
2917 return false;
|
|
2918 }
|
|
2919
|
|
2920 /* ISMA specific operations */
|
|
2921
|
|
2922 extern "C" bool MP4MakeIsmaCompliant(
|
|
2923 const char* fileName,
|
|
2924 u_int32_t verbosity,
|
|
2925 bool addIsmaComplianceSdp)
|
|
2926 {
|
|
2927 MP4File* pFile = NULL;
|
|
2928
|
|
2929 try {
|
|
2930 pFile = new MP4File(verbosity);
|
|
2931 pFile->Modify(fileName);
|
|
2932 pFile->MakeIsmaCompliant(addIsmaComplianceSdp);
|
|
2933 pFile->Close();
|
|
2934 delete pFile;
|
|
2935 return true;
|
|
2936 }
|
|
2937 catch (MP4Error* e) {
|
|
2938 VERBOSE_ERROR(verbosity, e->Print());
|
|
2939 delete e;
|
|
2940 }
|
|
2941 delete pFile;
|
|
2942 return false;
|
|
2943 }
|
|
2944
|
|
2945 extern "C" char* MP4MakeIsmaSdpIod(
|
|
2946 u_int8_t videoProfile,
|
|
2947 u_int32_t videoBitrate,
|
|
2948 u_int8_t* videoConfig,
|
|
2949 u_int32_t videoConfigLength,
|
|
2950 u_int8_t audioProfile,
|
|
2951 u_int32_t audioBitrate,
|
|
2952 u_int8_t* audioConfig,
|
|
2953 u_int32_t audioConfigLength,
|
|
2954 u_int32_t verbosity)
|
|
2955 {
|
|
2956 MP4File* pFile = NULL;
|
|
2957
|
|
2958 try {
|
|
2959 pFile = new MP4File(verbosity);
|
|
2960
|
|
2961 u_int8_t* pBytes = NULL;
|
|
2962 u_int64_t numBytes = 0;
|
|
2963
|
|
2964 pFile->CreateIsmaIodFromParams(
|
|
2965 videoProfile,
|
|
2966 videoBitrate,
|
|
2967 videoConfig,
|
|
2968 videoConfigLength,
|
|
2969 audioProfile,
|
|
2970 audioBitrate,
|
|
2971 audioConfig,
|
|
2972 audioConfigLength,
|
|
2973 &pBytes,
|
|
2974 &numBytes);
|
|
2975
|
|
2976 char* iodBase64 =
|
|
2977 MP4ToBase64(pBytes, numBytes);
|
|
2978 MP4Free(pBytes);
|
|
2979
|
|
2980 char* sdpIod =
|
|
2981 (char*)MP4Malloc(strlen(iodBase64) + 64);
|
|
2982 sprintf(sdpIod,
|
|
2983 "a=mpeg4-iod: \042data:application/mpeg4-iod;base64,%s\042",
|
|
2984 iodBase64);
|
|
2985 MP4Free(iodBase64);
|
|
2986
|
|
2987 delete pFile;
|
|
2988
|
|
2989 return sdpIod;
|
|
2990 }
|
|
2991 catch (MP4Error* e) {
|
|
2992 VERBOSE_ERROR(verbosity, e->Print());
|
|
2993 delete e;
|
|
2994 }
|
|
2995 delete pFile;
|
|
2996 return NULL;
|
|
2997 }
|
|
2998
|
|
2999 /* Edit list */
|
|
3000
|
|
3001 extern "C" MP4EditId MP4AddTrackEdit(
|
|
3002 MP4FileHandle hFile,
|
|
3003 MP4TrackId trackId,
|
|
3004 MP4EditId editId,
|
|
3005 MP4Timestamp startTime,
|
|
3006 MP4Duration duration,
|
|
3007 bool dwell)
|
|
3008 {
|
|
3009 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3010 try {
|
|
3011 MP4EditId newEditId =
|
|
3012 ((MP4File*)hFile)->AddTrackEdit(trackId, editId);
|
|
3013
|
|
3014 if (newEditId != MP4_INVALID_EDIT_ID) {
|
|
3015 ((MP4File*)hFile)->SetTrackEditMediaStart(
|
|
3016 trackId, newEditId, startTime);
|
|
3017 ((MP4File*)hFile)->SetTrackEditDuration(
|
|
3018 trackId, newEditId, duration);
|
|
3019 ((MP4File*)hFile)->SetTrackEditDwell(
|
|
3020 trackId, newEditId, dwell);
|
|
3021 }
|
|
3022
|
|
3023 return newEditId;
|
|
3024 }
|
|
3025 catch (MP4Error* e) {
|
|
3026 PRINT_ERROR(e);
|
|
3027 delete e;
|
|
3028 }
|
|
3029 }
|
|
3030 return MP4_INVALID_EDIT_ID;
|
|
3031 }
|
|
3032
|
|
3033 extern "C" bool MP4DeleteTrackEdit(
|
|
3034 MP4FileHandle hFile,
|
|
3035 MP4TrackId trackId,
|
|
3036 MP4EditId editId)
|
|
3037 {
|
|
3038 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3039 try {
|
|
3040 ((MP4File*)hFile)->DeleteTrackEdit(trackId, editId);
|
|
3041 return true;
|
|
3042 }
|
|
3043 catch (MP4Error* e) {
|
|
3044 PRINT_ERROR(e);
|
|
3045 delete e;
|
|
3046 }
|
|
3047 }
|
|
3048 return false;
|
|
3049 }
|
|
3050
|
|
3051 extern "C" u_int32_t MP4GetTrackNumberOfEdits(
|
|
3052 MP4FileHandle hFile,
|
|
3053 MP4TrackId trackId)
|
|
3054 {
|
|
3055 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3056 try {
|
|
3057 return ((MP4File*)hFile)->GetTrackNumberOfEdits(trackId);
|
|
3058 }
|
|
3059 catch (MP4Error* e) {
|
|
3060 PRINT_ERROR(e);
|
|
3061 delete e;
|
|
3062 }
|
|
3063 }
|
|
3064 return 0;
|
|
3065 }
|
|
3066
|
|
3067 extern "C" MP4Timestamp MP4GetTrackEditMediaStart(
|
|
3068 MP4FileHandle hFile,
|
|
3069 MP4TrackId trackId,
|
|
3070 MP4EditId editId)
|
|
3071 {
|
|
3072 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3073 try {
|
|
3074 return ((MP4File*)hFile)->GetTrackEditMediaStart(
|
|
3075 trackId, editId);
|
|
3076 }
|
|
3077 catch (MP4Error* e) {
|
|
3078 PRINT_ERROR(e);
|
|
3079 delete e;
|
|
3080 }
|
|
3081 }
|
|
3082 return MP4_INVALID_TIMESTAMP;
|
|
3083 }
|
|
3084
|
|
3085 extern "C" MP4Duration MP4GetTrackEditTotalDuration(
|
|
3086 MP4FileHandle hFile,
|
|
3087 MP4TrackId trackId,
|
|
3088 MP4EditId editId)
|
|
3089 {
|
|
3090 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3091 try {
|
|
3092 return ((MP4File*)hFile)->GetTrackEditTotalDuration(
|
|
3093 trackId, editId);
|
|
3094 }
|
|
3095 catch (MP4Error* e) {
|
|
3096 PRINT_ERROR(e);
|
|
3097 delete e;
|
|
3098 }
|
|
3099 }
|
|
3100 return MP4_INVALID_DURATION;
|
|
3101 }
|
|
3102
|
|
3103 extern "C" bool MP4SetTrackEditMediaStart(
|
|
3104 MP4FileHandle hFile,
|
|
3105 MP4TrackId trackId,
|
|
3106 MP4EditId editId,
|
|
3107 MP4Timestamp startTime)
|
|
3108 {
|
|
3109 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3110 try {
|
|
3111 ((MP4File*)hFile)->SetTrackEditMediaStart(
|
|
3112 trackId, editId, startTime);
|
|
3113 return true;
|
|
3114 }
|
|
3115 catch (MP4Error* e) {
|
|
3116 PRINT_ERROR(e);
|
|
3117 delete e;
|
|
3118 }
|
|
3119 }
|
|
3120 return false;
|
|
3121 }
|
|
3122
|
|
3123 extern "C" MP4Duration MP4GetTrackEditDuration(
|
|
3124 MP4FileHandle hFile,
|
|
3125 MP4TrackId trackId,
|
|
3126 MP4EditId editId)
|
|
3127 {
|
|
3128 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3129 try {
|
|
3130 return ((MP4File*)hFile)->GetTrackEditDuration(trackId, editId);
|
|
3131 }
|
|
3132 catch (MP4Error* e) {
|
|
3133 PRINT_ERROR(e);
|
|
3134 delete e;
|
|
3135 }
|
|
3136 }
|
|
3137 return MP4_INVALID_DURATION;
|
|
3138 }
|
|
3139
|
|
3140 extern "C" bool MP4SetTrackEditDuration(
|
|
3141 MP4FileHandle hFile,
|
|
3142 MP4TrackId trackId,
|
|
3143 MP4EditId editId,
|
|
3144 MP4Duration duration)
|
|
3145 {
|
|
3146 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3147 try {
|
|
3148 ((MP4File*)hFile)->SetTrackEditDuration(trackId, editId, duration);
|
|
3149 return true;
|
|
3150 }
|
|
3151 catch (MP4Error* e) {
|
|
3152 PRINT_ERROR(e);
|
|
3153 delete e;
|
|
3154 }
|
|
3155 }
|
|
3156 return false;
|
|
3157 }
|
|
3158
|
|
3159 extern "C" int8_t MP4GetTrackEditDwell(
|
|
3160 MP4FileHandle hFile,
|
|
3161 MP4TrackId trackId,
|
|
3162 MP4EditId editId)
|
|
3163 {
|
|
3164 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3165 try {
|
|
3166 return ((MP4File*)hFile)->GetTrackEditDwell(trackId, editId);
|
|
3167 }
|
|
3168 catch (MP4Error* e) {
|
|
3169 PRINT_ERROR(e);
|
|
3170 delete e;
|
|
3171 }
|
|
3172 }
|
|
3173 return -1;
|
|
3174 }
|
|
3175
|
|
3176 extern "C" bool MP4SetTrackEditDwell(
|
|
3177 MP4FileHandle hFile,
|
|
3178 MP4TrackId trackId,
|
|
3179 MP4EditId editId,
|
|
3180 bool dwell)
|
|
3181 {
|
|
3182 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3183 try {
|
|
3184 ((MP4File*)hFile)->SetTrackEditDwell(trackId, editId, dwell);
|
|
3185 return true;
|
|
3186 }
|
|
3187 catch (MP4Error* e) {
|
|
3188 PRINT_ERROR(e);
|
|
3189 delete e;
|
|
3190 }
|
|
3191 }
|
|
3192 return false;
|
|
3193 }
|
|
3194
|
|
3195 extern "C" bool MP4ReadSampleFromEditTime(
|
|
3196 /* input parameters */
|
|
3197 MP4FileHandle hFile,
|
|
3198 MP4TrackId trackId,
|
|
3199 MP4Timestamp when,
|
|
3200 /* output parameters */
|
|
3201 u_int8_t** ppBytes,
|
|
3202 u_int32_t* pNumBytes,
|
|
3203 MP4Timestamp* pStartTime,
|
|
3204 MP4Duration* pDuration,
|
|
3205 MP4Duration* pRenderingOffset,
|
|
3206 bool* pIsSyncSample)
|
|
3207 {
|
|
3208 MP4SampleId sampleId =
|
|
3209 MP4GetSampleIdFromEditTime(
|
|
3210 hFile,
|
|
3211 trackId,
|
|
3212 when,
|
|
3213 pStartTime,
|
|
3214 pDuration);
|
|
3215
|
|
3216 return MP4ReadSample(
|
|
3217 hFile,
|
|
3218 trackId,
|
|
3219 sampleId,
|
|
3220 ppBytes,
|
|
3221 pNumBytes,
|
|
3222 NULL,
|
|
3223 NULL,
|
|
3224 pRenderingOffset,
|
|
3225 pIsSyncSample);
|
|
3226 }
|
|
3227
|
|
3228 extern "C" MP4SampleId MP4GetSampleIdFromEditTime(
|
|
3229 MP4FileHandle hFile,
|
|
3230 MP4TrackId trackId,
|
|
3231 MP4Timestamp when,
|
|
3232 MP4Timestamp* pStartTime,
|
|
3233 MP4Duration* pDuration)
|
|
3234 {
|
|
3235 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3236 try {
|
|
3237 return ((MP4File*)hFile)->GetSampleIdFromEditTime(
|
|
3238 trackId, when, pStartTime, pDuration);
|
|
3239 }
|
|
3240 catch (MP4Error* e) {
|
|
3241 PRINT_ERROR(e);
|
|
3242 delete e;
|
|
3243 }
|
|
3244 }
|
|
3245 return MP4_INVALID_SAMPLE_ID;
|
|
3246 }
|
|
3247
|
|
3248 /* Utlities */
|
|
3249
|
|
3250 extern "C" char* MP4BinaryToBase16(
|
|
3251 const u_int8_t* pData,
|
|
3252 u_int32_t dataSize)
|
|
3253 {
|
|
3254 if (pData || dataSize == 0) {
|
|
3255 try {
|
|
3256 return MP4ToBase16(pData, dataSize);
|
|
3257 }
|
|
3258 catch (MP4Error* e) {
|
|
3259 delete e;
|
|
3260 }
|
|
3261 }
|
|
3262 return NULL;
|
|
3263 }
|
|
3264
|
|
3265 extern "C" char* MP4BinaryToBase64(
|
|
3266 const u_int8_t* pData,
|
|
3267 u_int32_t dataSize)
|
|
3268 {
|
|
3269 if (pData || dataSize == 0) {
|
|
3270 try {
|
|
3271 return MP4ToBase64(pData, dataSize);
|
|
3272 }
|
|
3273 catch (MP4Error* e) {
|
|
3274 delete e;
|
|
3275 }
|
|
3276 }
|
|
3277 return NULL;
|
|
3278 }
|
|
3279
|
|
3280 /* iTunes meta data handling */
|
|
3281 extern "C" bool MP4GetMetadataByIndex(MP4FileHandle hFile, u_int32_t index,
|
|
3282 const char** ppName,
|
|
3283 u_int8_t** ppValue, u_int32_t* pValueSize)
|
|
3284 {
|
|
3285 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3286 try {
|
|
3287 return ((MP4File*)hFile)->GetMetadataByIndex(
|
|
3288 index, ppName, ppValue, pValueSize);
|
|
3289 }
|
|
3290 catch (MP4Error* e) {
|
|
3291 PRINT_ERROR(e);
|
|
3292 delete e;
|
|
3293 }
|
|
3294 }
|
|
3295 return false;
|
|
3296 }
|
|
3297
|
|
3298 extern "C" bool MP4MetadataDelete(MP4FileHandle hFile)
|
|
3299 {
|
|
3300 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3301 try {
|
|
3302 return ((MP4File*)hFile)->MetadataDelete();
|
|
3303 }
|
|
3304 catch (MP4Error* e) {
|
|
3305 PRINT_ERROR(e);
|
|
3306 delete e;
|
|
3307 }
|
|
3308 }
|
|
3309 return false;
|
|
3310 }
|
|
3311
|
|
3312 extern "C" bool MP4SetMetadataName(MP4FileHandle hFile,
|
|
3313 const char* value)
|
|
3314 {
|
|
3315 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3316 try {
|
|
3317 return ((MP4File*)hFile)->SetMetadataName(value);
|
|
3318 }
|
|
3319 catch (MP4Error* e) {
|
|
3320 PRINT_ERROR(e);
|
|
3321 delete e;
|
|
3322 }
|
|
3323 }
|
|
3324 return false;
|
|
3325 }
|
|
3326
|
|
3327 extern "C" bool MP4GetMetadataName(MP4FileHandle hFile,
|
|
3328 char** value)
|
|
3329 {
|
|
3330 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3331 try {
|
|
3332 return ((MP4File*)hFile)->GetMetadataName(value);
|
|
3333 }
|
|
3334 catch (MP4Error* e) {
|
|
3335 PRINT_ERROR(e);
|
|
3336 delete e;
|
|
3337 }
|
|
3338 }
|
|
3339 return false;
|
|
3340 }
|
|
3341
|
|
3342 extern "C" bool MP4DeleteMetadataName(MP4FileHandle hFile)
|
|
3343 {
|
|
3344 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3345 try {
|
|
3346 return ((MP4File*)hFile)->DeleteMetadataName();
|
|
3347 }
|
|
3348 catch (MP4Error* e) {
|
|
3349 PRINT_ERROR(e);
|
|
3350 delete e;
|
|
3351 }
|
|
3352 }
|
|
3353 return false;
|
|
3354 }
|
|
3355
|
|
3356 extern "C" bool MP4SetMetadataWriter(MP4FileHandle hFile,
|
|
3357 const char* value)
|
|
3358 {
|
|
3359 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3360 try {
|
|
3361 return ((MP4File*)hFile)->SetMetadataWriter(value);
|
|
3362 }
|
|
3363 catch (MP4Error* e) {
|
|
3364 PRINT_ERROR(e);
|
|
3365 delete e;
|
|
3366 }
|
|
3367 }
|
|
3368 return false;
|
|
3369 }
|
|
3370
|
|
3371 extern "C" bool MP4GetMetadataWriter(MP4FileHandle hFile,
|
|
3372 char** value)
|
|
3373 {
|
|
3374 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3375 try {
|
|
3376 return ((MP4File*)hFile)->GetMetadataWriter(value);
|
|
3377 }
|
|
3378 catch (MP4Error* e) {
|
|
3379 PRINT_ERROR(e);
|
|
3380 delete e;
|
|
3381 }
|
|
3382 }
|
|
3383 return false;
|
|
3384 }
|
|
3385
|
|
3386 extern "C" bool MP4DeleteMetadataWriter(MP4FileHandle hFile)
|
|
3387 {
|
|
3388 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3389 try {
|
|
3390 return ((MP4File*)hFile)->DeleteMetadataWriter();
|
|
3391 }
|
|
3392 catch (MP4Error* e) {
|
|
3393 PRINT_ERROR(e);
|
|
3394 delete e;
|
|
3395 }
|
|
3396 }
|
|
3397 return false;
|
|
3398 }
|
|
3399
|
|
3400 extern "C" bool MP4SetMetadataAlbum(MP4FileHandle hFile,
|
|
3401 const char* value)
|
|
3402 {
|
|
3403 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3404 try {
|
|
3405 return ((MP4File*)hFile)->SetMetadataAlbum(value);
|
|
3406 }
|
|
3407 catch (MP4Error* e) {
|
|
3408 PRINT_ERROR(e);
|
|
3409 delete e;
|
|
3410 }
|
|
3411 }
|
|
3412 return false;
|
|
3413 }
|
|
3414
|
|
3415 extern "C" bool MP4GetMetadataAlbum(MP4FileHandle hFile,
|
|
3416 char** value)
|
|
3417 {
|
|
3418 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3419 try {
|
|
3420 return ((MP4File*)hFile)->GetMetadataAlbum(value);
|
|
3421 }
|
|
3422 catch (MP4Error* e) {
|
|
3423 PRINT_ERROR(e);
|
|
3424 delete e;
|
|
3425 }
|
|
3426 }
|
|
3427 return false;
|
|
3428 }
|
|
3429
|
|
3430 extern "C" bool MP4DeleteMetadataAlbum(MP4FileHandle hFile)
|
|
3431 {
|
|
3432 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3433 try {
|
|
3434 return ((MP4File*)hFile)->DeleteMetadataAlbum();
|
|
3435 }
|
|
3436 catch (MP4Error* e) {
|
|
3437 PRINT_ERROR(e);
|
|
3438 delete e;
|
|
3439 }
|
|
3440 }
|
|
3441 return false;
|
|
3442 }
|
|
3443
|
|
3444 extern "C" bool MP4SetMetadataArtist(MP4FileHandle hFile,
|
|
3445 const char* value)
|
|
3446 {
|
|
3447 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3448 try {
|
|
3449 return ((MP4File*)hFile)->SetMetadataArtist(value);
|
|
3450 }
|
|
3451 catch (MP4Error* e) {
|
|
3452 PRINT_ERROR(e);
|
|
3453 delete e;
|
|
3454 }
|
|
3455 }
|
|
3456 return false;
|
|
3457 }
|
|
3458
|
|
3459 extern "C" bool MP4GetMetadataArtist(MP4FileHandle hFile,
|
|
3460 char** value)
|
|
3461 {
|
|
3462 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3463 try {
|
|
3464 return ((MP4File*)hFile)->GetMetadataArtist(value);
|
|
3465 }
|
|
3466 catch (MP4Error* e) {
|
|
3467 PRINT_ERROR(e);
|
|
3468 delete e;
|
|
3469 }
|
|
3470 }
|
|
3471 return false;
|
|
3472 }
|
|
3473
|
|
3474 extern "C" bool MP4DeleteMetadataArtist(MP4FileHandle hFile)
|
|
3475 {
|
|
3476 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3477 try {
|
|
3478 return ((MP4File*)hFile)->DeleteMetadataArtist();
|
|
3479 }
|
|
3480 catch (MP4Error* e) {
|
|
3481 PRINT_ERROR(e);
|
|
3482 delete e;
|
|
3483 }
|
|
3484 }
|
|
3485 return false;
|
|
3486 }
|
|
3487
|
|
3488 extern "C" bool MP4SetMetadataTool(MP4FileHandle hFile,
|
|
3489 const char* value)
|
|
3490 {
|
|
3491 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3492 try {
|
|
3493 return ((MP4File*)hFile)->SetMetadataTool(value);
|
|
3494 }
|
|
3495 catch (MP4Error* e) {
|
|
3496 PRINT_ERROR(e);
|
|
3497 delete e;
|
|
3498 }
|
|
3499 }
|
|
3500 return false;
|
|
3501 }
|
|
3502
|
|
3503 extern "C" bool MP4GetMetadataTool(MP4FileHandle hFile,
|
|
3504 char** value)
|
|
3505 {
|
|
3506 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3507 try {
|
|
3508 return ((MP4File*)hFile)->GetMetadataTool(value);
|
|
3509 }
|
|
3510 catch (MP4Error* e) {
|
|
3511 PRINT_ERROR(e);
|
|
3512 delete e;
|
|
3513 }
|
|
3514 }
|
|
3515 return false;
|
|
3516 }
|
|
3517
|
|
3518 extern "C" bool MP4DeleteMetadataTool(MP4FileHandle hFile)
|
|
3519 {
|
|
3520 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3521 try {
|
|
3522 return ((MP4File*)hFile)->DeleteMetadataTool();
|
|
3523 }
|
|
3524 catch (MP4Error* e) {
|
|
3525 PRINT_ERROR(e);
|
|
3526 delete e;
|
|
3527 }
|
|
3528 }
|
|
3529 return false;
|
|
3530 }
|
|
3531
|
|
3532 extern "C" bool MP4SetMetadataComment(MP4FileHandle hFile,
|
|
3533 const char* value)
|
|
3534 {
|
|
3535 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3536 try {
|
|
3537 return ((MP4File*)hFile)->SetMetadataComment(value);
|
|
3538 }
|
|
3539 catch (MP4Error* e) {
|
|
3540 PRINT_ERROR(e);
|
|
3541 delete e;
|
|
3542 }
|
|
3543 }
|
|
3544 return false;
|
|
3545 }
|
|
3546
|
|
3547 extern "C" bool MP4GetMetadataComment(MP4FileHandle hFile,
|
|
3548 char** value)
|
|
3549 {
|
|
3550 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3551 try {
|
|
3552 return ((MP4File*)hFile)->GetMetadataComment(value);
|
|
3553 }
|
|
3554 catch (MP4Error* e) {
|
|
3555 PRINT_ERROR(e);
|
|
3556 delete e;
|
|
3557 }
|
|
3558 }
|
|
3559 return false;
|
|
3560 }
|
|
3561
|
|
3562 extern "C" bool MP4DeleteMetadataComment(MP4FileHandle hFile)
|
|
3563 {
|
|
3564 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3565 try {
|
|
3566 return ((MP4File*)hFile)->DeleteMetadataComment();
|
|
3567 }
|
|
3568 catch (MP4Error* e) {
|
|
3569 PRINT_ERROR(e);
|
|
3570 delete e;
|
|
3571 }
|
|
3572 }
|
|
3573 return false;
|
|
3574 }
|
|
3575
|
|
3576 extern "C" bool MP4SetMetadataYear(MP4FileHandle hFile,
|
|
3577 const char* value)
|
|
3578 {
|
|
3579 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3580 try {
|
|
3581 return ((MP4File*)hFile)->SetMetadataYear(value);
|
|
3582 }
|
|
3583 catch (MP4Error* e) {
|
|
3584 PRINT_ERROR(e);
|
|
3585 delete e;
|
|
3586 }
|
|
3587 }
|
|
3588 return false;
|
|
3589 }
|
|
3590
|
|
3591 extern "C" bool MP4GetMetadataYear(MP4FileHandle hFile,
|
|
3592 char** value)
|
|
3593 {
|
|
3594 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3595 try {
|
|
3596 return ((MP4File*)hFile)->GetMetadataYear(value);
|
|
3597 }
|
|
3598 catch (MP4Error* e) {
|
|
3599 PRINT_ERROR(e);
|
|
3600 delete e;
|
|
3601 }
|
|
3602 }
|
|
3603 return false;
|
|
3604 }
|
|
3605
|
|
3606 extern "C" bool MP4DeleteMetadataYear(MP4FileHandle hFile)
|
|
3607 {
|
|
3608 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3609 try {
|
|
3610 return ((MP4File*)hFile)->DeleteMetadataYear();
|
|
3611 }
|
|
3612 catch (MP4Error* e) {
|
|
3613 PRINT_ERROR(e);
|
|
3614 delete e;
|
|
3615 }
|
|
3616 }
|
|
3617 return false;
|
|
3618 }
|
|
3619
|
|
3620 extern "C" bool MP4SetMetadataTrack(MP4FileHandle hFile,
|
|
3621 u_int16_t track, u_int16_t totalTracks)
|
|
3622 {
|
|
3623 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3624 try {
|
|
3625 return ((MP4File*)hFile)->SetMetadataTrack(track, totalTracks);
|
|
3626 }
|
|
3627 catch (MP4Error* e) {
|
|
3628 PRINT_ERROR(e);
|
|
3629 delete e;
|
|
3630 }
|
|
3631 }
|
|
3632 return false;
|
|
3633 }
|
|
3634
|
|
3635 extern "C" bool MP4GetMetadataTrack(MP4FileHandle hFile,
|
|
3636 u_int16_t* track, u_int16_t* totalTracks)
|
|
3637 {
|
|
3638 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3639 try {
|
|
3640 return ((MP4File*)hFile)->GetMetadataTrack(track, totalTracks);
|
|
3641 }
|
|
3642 catch (MP4Error* e) {
|
|
3643 PRINT_ERROR(e);
|
|
3644 delete e;
|
|
3645 }
|
|
3646 }
|
|
3647 return false;
|
|
3648 }
|
|
3649
|
|
3650 extern "C" bool MP4DeleteMetadataTrack(MP4FileHandle hFile)
|
|
3651 {
|
|
3652 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3653 try {
|
|
3654 return ((MP4File*)hFile)->DeleteMetadataTrack();
|
|
3655 }
|
|
3656 catch (MP4Error* e) {
|
|
3657 PRINT_ERROR(e);
|
|
3658 delete e;
|
|
3659 }
|
|
3660 }
|
|
3661 return false;
|
|
3662 }
|
|
3663
|
|
3664 extern "C" bool MP4SetMetadataDisk(MP4FileHandle hFile,
|
|
3665 u_int16_t disk, u_int16_t totalDisks)
|
|
3666 {
|
|
3667 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3668 try {
|
|
3669 return ((MP4File*)hFile)->SetMetadataDisk(disk, totalDisks);
|
|
3670 }
|
|
3671 catch (MP4Error* e) {
|
|
3672 PRINT_ERROR(e);
|
|
3673 delete e;
|
|
3674 }
|
|
3675 }
|
|
3676 return false;
|
|
3677 }
|
|
3678
|
|
3679 extern "C" bool MP4GetMetadataDisk(MP4FileHandle hFile,
|
|
3680 u_int16_t* disk, u_int16_t* totalDisks)
|
|
3681 {
|
|
3682 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3683 try {
|
|
3684 return ((MP4File*)hFile)->GetMetadataDisk(disk, totalDisks);
|
|
3685 }
|
|
3686 catch (MP4Error* e) {
|
|
3687 PRINT_ERROR(e);
|
|
3688 delete e;
|
|
3689 }
|
|
3690 }
|
|
3691 return false;
|
|
3692 }
|
|
3693
|
|
3694 extern "C" bool MP4DeleteMetadataDisk(MP4FileHandle hFile)
|
|
3695 {
|
|
3696 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3697 try {
|
|
3698 return ((MP4File*)hFile)->DeleteMetadataDisk();
|
|
3699 }
|
|
3700 catch (MP4Error* e) {
|
|
3701 PRINT_ERROR(e);
|
|
3702 delete e;
|
|
3703 }
|
|
3704 }
|
|
3705 return false;
|
|
3706 }
|
|
3707
|
|
3708 extern "C" bool MP4SetMetadataGenre(MP4FileHandle hFile, const char *genre)
|
|
3709 {
|
|
3710 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3711 try {
|
|
3712 return ((MP4File*)hFile)->SetMetadataGenre(genre);
|
|
3713 }
|
|
3714 catch (MP4Error* e) {
|
|
3715 PRINT_ERROR(e);
|
|
3716 delete e;
|
|
3717 }
|
|
3718 }
|
|
3719 return false;
|
|
3720 }
|
|
3721
|
|
3722 extern "C" bool MP4GetMetadataGenre(MP4FileHandle hFile, char **genre)
|
|
3723 {
|
|
3724 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3725 try {
|
|
3726 return ((MP4File*)hFile)->GetMetadataGenre(genre);
|
|
3727 }
|
|
3728 catch (MP4Error* e) {
|
|
3729 PRINT_ERROR(e);
|
|
3730 delete e;
|
|
3731 }
|
|
3732 }
|
|
3733 return false;
|
|
3734 }
|
|
3735
|
|
3736 extern "C" bool MP4DeleteMetadataGenre(MP4FileHandle hFile)
|
|
3737 {
|
|
3738 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3739 try {
|
|
3740 return ((MP4File*)hFile)->DeleteMetadataGenre();
|
|
3741 }
|
|
3742 catch (MP4Error* e) {
|
|
3743 PRINT_ERROR(e);
|
|
3744 delete e;
|
|
3745 }
|
|
3746 }
|
|
3747 return false;
|
|
3748 }
|
|
3749
|
|
3750 extern "C" bool MP4SetMetadataGrouping(MP4FileHandle hFile, const char *grouping)
|
|
3751 {
|
|
3752 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3753 try {
|
|
3754 return ((MP4File*)hFile)->SetMetadataGrouping(grouping);
|
|
3755 }
|
|
3756 catch (MP4Error* e) {
|
|
3757 PRINT_ERROR(e);
|
|
3758 delete e;
|
|
3759 }
|
|
3760 }
|
|
3761 return false;
|
|
3762 }
|
|
3763
|
|
3764 extern "C" bool MP4GetMetadataGrouping(MP4FileHandle hFile, char **grouping)
|
|
3765 {
|
|
3766 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3767 try {
|
|
3768 return ((MP4File*)hFile)->GetMetadataGrouping(grouping);
|
|
3769 }
|
|
3770 catch (MP4Error* e) {
|
|
3771 PRINT_ERROR(e);
|
|
3772 delete e;
|
|
3773 }
|
|
3774 }
|
|
3775 return false;
|
|
3776 }
|
|
3777
|
|
3778 extern "C" bool MP4DeleteMetadataGrouping(MP4FileHandle hFile)
|
|
3779 {
|
|
3780 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3781 try {
|
|
3782 return ((MP4File*)hFile)->DeleteMetadataGrouping();
|
|
3783 }
|
|
3784 catch (MP4Error* e) {
|
|
3785 PRINT_ERROR(e);
|
|
3786 delete e;
|
|
3787 }
|
|
3788 }
|
|
3789 return false;
|
|
3790 }
|
|
3791
|
|
3792 extern "C" bool MP4SetMetadataTempo(MP4FileHandle hFile, u_int16_t tempo)
|
|
3793 {
|
|
3794 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3795 try {
|
|
3796 return ((MP4File*)hFile)->SetMetadataTempo(tempo);
|
|
3797 }
|
|
3798 catch (MP4Error* e) {
|
|
3799 PRINT_ERROR(e);
|
|
3800 delete e;
|
|
3801 }
|
|
3802 }
|
|
3803 return false;
|
|
3804 }
|
|
3805
|
|
3806 extern "C" bool MP4GetMetadataTempo(MP4FileHandle hFile, u_int16_t* tempo)
|
|
3807 {
|
|
3808 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3809 try {
|
|
3810 return ((MP4File*)hFile)->GetMetadataTempo(tempo);
|
|
3811 }
|
|
3812 catch (MP4Error* e) {
|
|
3813 PRINT_ERROR(e);
|
|
3814 delete e;
|
|
3815 }
|
|
3816 }
|
|
3817 return false;
|
|
3818 }
|
|
3819
|
|
3820 extern "C" bool MP4DeleteMetadataTempo(MP4FileHandle hFile)
|
|
3821 {
|
|
3822 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3823 try {
|
|
3824 return ((MP4File*)hFile)->DeleteMetadataTempo();
|
|
3825 }
|
|
3826 catch (MP4Error* e) {
|
|
3827 PRINT_ERROR(e);
|
|
3828 delete e;
|
|
3829 }
|
|
3830 }
|
|
3831 return false;
|
|
3832 }
|
|
3833
|
|
3834 extern "C" bool MP4SetMetadataCompilation(MP4FileHandle hFile, u_int8_t cpl)
|
|
3835 {
|
|
3836 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3837 try {
|
|
3838 return ((MP4File*)hFile)->SetMetadataCompilation(cpl);
|
|
3839 }
|
|
3840 catch (MP4Error* e) {
|
|
3841 PRINT_ERROR(e);
|
|
3842 delete e;
|
|
3843 }
|
|
3844 }
|
|
3845 return false;
|
|
3846 }
|
|
3847
|
|
3848 extern "C" bool MP4GetMetadataCompilation(MP4FileHandle hFile, u_int8_t* cpl)
|
|
3849 {
|
|
3850 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3851 try {
|
|
3852 return ((MP4File*)hFile)->GetMetadataCompilation(cpl);
|
|
3853 }
|
|
3854 catch (MP4Error* e) {
|
|
3855 PRINT_ERROR(e);
|
|
3856 delete e;
|
|
3857 }
|
|
3858 }
|
|
3859 return false;
|
|
3860 }
|
|
3861
|
|
3862 extern "C" bool MP4DeleteMetadataCompilation(MP4FileHandle hFile)
|
|
3863 {
|
|
3864 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3865 try {
|
|
3866 return ((MP4File*)hFile)->DeleteMetadataCompilation();
|
|
3867 }
|
|
3868 catch (MP4Error* e) {
|
|
3869 PRINT_ERROR(e);
|
|
3870 delete e;
|
|
3871 }
|
|
3872 }
|
|
3873 return false;
|
|
3874 }
|
|
3875
|
|
3876 extern "C" bool MP4SetMetadataCoverArt(MP4FileHandle hFile,
|
|
3877 u_int8_t *coverArt, u_int32_t size)
|
|
3878 {
|
|
3879 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3880 try {
|
|
3881 return ((MP4File*)hFile)->SetMetadataCoverArt(coverArt, size);
|
|
3882 }
|
|
3883 catch (MP4Error* e) {
|
|
3884 PRINT_ERROR(e);
|
|
3885 delete e;
|
|
3886 }
|
|
3887 }
|
|
3888 return false;
|
|
3889 }
|
|
3890
|
|
3891 extern "C" bool MP4GetMetadataCoverArt(MP4FileHandle hFile,
|
|
3892 u_int8_t **coverArt, u_int32_t* size)
|
|
3893 {
|
|
3894 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3895 try {
|
|
3896 return ((MP4File*)hFile)->GetMetadataCoverArt(coverArt, size);
|
|
3897 }
|
|
3898 catch (MP4Error* e) {
|
|
3899 PRINT_ERROR(e);
|
|
3900 delete e;
|
|
3901 }
|
|
3902 }
|
|
3903 return false;
|
|
3904 }
|
|
3905
|
|
3906 extern "C" bool MP4DeleteMetadataCoverArt(MP4FileHandle hFile)
|
|
3907 {
|
|
3908 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3909 try {
|
|
3910 return ((MP4File*)hFile)->DeleteMetadataCoverArt();
|
|
3911 }
|
|
3912 catch (MP4Error* e) {
|
|
3913 PRINT_ERROR(e);
|
|
3914 delete e;
|
|
3915 }
|
|
3916 }
|
|
3917 return false;
|
|
3918 }
|
|
3919
|
|
3920 extern "C" bool MP4SetMetadataFreeForm(MP4FileHandle hFile, char *name,
|
|
3921 u_int8_t* pValue, u_int32_t valueSize)
|
|
3922 {
|
|
3923 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3924 try {
|
|
3925 return ((MP4File*)hFile)->SetMetadataFreeForm(name, pValue, valueSize);
|
|
3926 }
|
|
3927 catch (MP4Error* e) {
|
|
3928 PRINT_ERROR(e);
|
|
3929 delete e;
|
|
3930 }
|
|
3931 }
|
|
3932 return false;
|
|
3933 }
|
|
3934
|
|
3935 extern "C" bool MP4GetMetadataFreeForm(MP4FileHandle hFile, char *name,
|
|
3936 u_int8_t** pValue, u_int32_t* valueSize)
|
|
3937 {
|
|
3938 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3939 try {
|
|
3940 return ((MP4File*)hFile)->GetMetadataFreeForm(name, pValue, valueSize);
|
|
3941 }
|
|
3942 catch (MP4Error* e) {
|
|
3943 PRINT_ERROR(e);
|
|
3944 delete e;
|
|
3945 }
|
|
3946 }
|
|
3947 return false;
|
|
3948 }
|
|
3949
|
|
3950 extern "C" bool MP4DeleteMetadataFreeForm(MP4FileHandle hFile, char *name)
|
|
3951 {
|
|
3952 if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
|
|
3953 try {
|
|
3954 return ((MP4File*)hFile)->DeleteMetadataFreeForm(name);
|
|
3955 }
|
|
3956 catch (MP4Error* e) {
|
|
3957 PRINT_ERROR(e);
|
|
3958 delete e;
|
|
3959 }
|
|
3960 }
|
|
3961 return false;
|
|
3962 }
|
|
3963
|