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