mp4.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:48k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  */
  21. /* 
  22.  * MP4 library API functions
  23.  * 
  24.  * These are wrapper functions that provide C linkage conventions
  25.  * to the library, and catch any internal errors, ensuring that
  26.  * a proper return value is given.
  27.  */
  28. #include "mp4common.h"
  29. #define PRINT_ERROR(e) 
  30. VERBOSE_ERROR(((MP4File*)hFile)->GetVerbosity(), e->Print());
  31. /* file operations */
  32. extern "C" MP4FileHandle MP4Read(const char* fileName, u_int32_t verbosity)
  33. {
  34. MP4File* pFile = NULL;
  35. try {
  36. pFile = new MP4File(verbosity);
  37. pFile->Read(fileName);
  38. return (MP4FileHandle)pFile;
  39. }
  40. catch (MP4Error* e) {
  41. VERBOSE_ERROR(verbosity, e->Print());
  42. delete e;
  43. delete pFile;
  44. return MP4_INVALID_FILE_HANDLE;
  45. }
  46. }
  47. extern "C" MP4FileHandle MP4Create(const char* fileName, 
  48. u_int32_t verbosity, bool use64bits, bool useExtensibleFormat)
  49. {
  50. MP4File* pFile = NULL;
  51. try {
  52. pFile = new MP4File(verbosity);
  53. // LATER useExtensibleFormat, moov first, then mvex's
  54. pFile->Create(fileName, use64bits);
  55. return (MP4FileHandle)pFile;
  56. }
  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. extern "C" MP4FileHandle MP4Modify(const char* fileName, 
  65. u_int32_t verbosity, bool useExtensibleFormat)
  66. {
  67. MP4File* pFile = NULL;
  68. try {
  69. pFile = new MP4File(verbosity);
  70. // LATER useExtensibleFormat, moov first, then mvex's
  71. pFile->Modify(fileName);
  72. return (MP4FileHandle)pFile;
  73. }
  74. catch (MP4Error* e) {
  75. VERBOSE_ERROR(verbosity, e->Print());
  76. delete e;
  77. delete pFile;
  78. return MP4_INVALID_FILE_HANDLE;
  79. }
  80. }
  81. extern "C" bool MP4Optimize(const char* existingFileName, 
  82. const char* newFileName, 
  83. u_int32_t verbosity)
  84. {
  85. try {
  86. MP4File* pFile = new MP4File(verbosity);
  87. pFile->Optimize(existingFileName, newFileName);
  88. delete pFile;
  89. return true;
  90. }
  91. catch (MP4Error* e) {
  92. VERBOSE_ERROR(verbosity, e->Print());
  93. delete e;
  94. }
  95. return false;
  96. }
  97. extern "C" bool MP4Close(MP4FileHandle hFile)
  98. {
  99. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  100. try {
  101. ((MP4File*)hFile)->Close();
  102. delete (MP4File*)hFile;
  103. return true;
  104. }
  105. catch (MP4Error* e) {
  106. PRINT_ERROR(e);
  107. delete e;
  108. }
  109. }
  110. return false;
  111. }
  112. extern "C" bool MP4Dump(
  113. MP4FileHandle hFile, 
  114. FILE* pDumpFile, 
  115. bool dumpImplicits)
  116. {
  117. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  118. try {
  119. ((MP4File*)hFile)->Dump(pDumpFile, dumpImplicits);
  120. return true;
  121. }
  122. catch (MP4Error* e) {
  123. PRINT_ERROR(e);
  124. delete e;
  125. }
  126. }
  127. return false;
  128. }
  129. /* specific file properties */
  130. extern "C" u_int32_t MP4GetVerbosity(MP4FileHandle hFile)
  131. {
  132. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  133. try {
  134. return ((MP4File*)hFile)->GetVerbosity();
  135. }
  136. catch (MP4Error* e) {
  137. PRINT_ERROR(e);
  138. delete e;
  139. }
  140. }
  141. return 0;
  142. }
  143. extern "C" bool MP4SetVerbosity(MP4FileHandle hFile, u_int32_t verbosity)
  144. {
  145. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  146. try {
  147. ((MP4File*)hFile)->SetVerbosity(verbosity);
  148. return true;
  149. }
  150. catch (MP4Error* e) {
  151. PRINT_ERROR(e);
  152. delete e;
  153. }
  154. }
  155. return false;
  156. }
  157. extern "C" MP4Duration MP4GetDuration(MP4FileHandle hFile)
  158. {
  159. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  160. try {
  161. return ((MP4File*)hFile)->GetDuration();
  162. }
  163. catch (MP4Error* e) {
  164. PRINT_ERROR(e);
  165. delete e;
  166. }
  167. }
  168. return MP4_INVALID_DURATION;
  169. }
  170. extern "C" u_int32_t MP4GetTimeScale(MP4FileHandle hFile)
  171. {
  172. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  173. try {
  174. return ((MP4File*)hFile)->GetTimeScale();
  175. }
  176. catch (MP4Error* e) {
  177. PRINT_ERROR(e);
  178. delete e;
  179. }
  180. }
  181. return 0;
  182. }
  183. extern "C" bool MP4SetTimeScale(MP4FileHandle hFile, u_int32_t value)
  184. {
  185. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  186. try {
  187. ((MP4File*)hFile)->SetTimeScale(value);
  188. return true;
  189. }
  190. catch (MP4Error* e) {
  191. PRINT_ERROR(e);
  192. delete e;
  193. }
  194. }
  195. return false;
  196. }
  197. extern "C" u_int8_t MP4GetODProfileLevel(MP4FileHandle hFile)
  198. {
  199. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  200. try {
  201. return ((MP4File*)hFile)->GetODProfileLevel();
  202. }
  203. catch (MP4Error* e) {
  204. PRINT_ERROR(e);
  205. delete e;
  206. }
  207. }
  208. return 0;
  209. }
  210. extern "C" bool MP4SetODProfileLevel(MP4FileHandle hFile, u_int8_t value)
  211. {
  212. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  213. try {
  214. ((MP4File*)hFile)->SetODProfileLevel(value);
  215. return true;
  216. }
  217. catch (MP4Error* e) {
  218. PRINT_ERROR(e);
  219. delete e;
  220. }
  221. }
  222. return false;
  223. }
  224. extern "C" u_int8_t MP4GetSceneProfileLevel(MP4FileHandle hFile)
  225. {
  226. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  227. try {
  228. return ((MP4File*)hFile)->GetSceneProfileLevel();
  229. }
  230. catch (MP4Error* e) {
  231. PRINT_ERROR(e);
  232. delete e;
  233. }
  234. }
  235. return 0;
  236. }
  237. extern "C" bool MP4SetSceneProfileLevel(MP4FileHandle hFile, u_int8_t value)
  238. {
  239. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  240. try {
  241. ((MP4File*)hFile)->SetSceneProfileLevel(value);
  242. return true;
  243. }
  244. catch (MP4Error* e) {
  245. PRINT_ERROR(e);
  246. delete e;
  247. }
  248. }
  249. return false;
  250. }
  251. extern "C" u_int8_t MP4GetVideoProfileLevel(MP4FileHandle hFile)
  252. {
  253. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  254. try {
  255. return ((MP4File*)hFile)->GetVideoProfileLevel();
  256. }
  257. catch (MP4Error* e) {
  258. PRINT_ERROR(e);
  259. delete e;
  260. }
  261. }
  262. return 0;
  263. }
  264. extern "C" bool MP4SetVideoProfileLevel(MP4FileHandle hFile, u_int8_t value)
  265. {
  266. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  267. try {
  268. ((MP4File*)hFile)->SetVideoProfileLevel(value);
  269. return true;
  270. }
  271. catch (MP4Error* e) {
  272. PRINT_ERROR(e);
  273. delete e;
  274. }
  275. }
  276. return false;
  277. }
  278. extern "C" u_int8_t MP4GetAudioProfileLevel(MP4FileHandle hFile)
  279. {
  280. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  281. try {
  282. return ((MP4File*)hFile)->GetAudioProfileLevel();
  283. }
  284. catch (MP4Error* e) {
  285. PRINT_ERROR(e);
  286. delete e;
  287. }
  288. }
  289. return 0;
  290. }
  291. extern "C" bool MP4SetAudioProfileLevel(MP4FileHandle hFile, u_int8_t value)
  292. {
  293. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  294. try {
  295. ((MP4File*)hFile)->SetAudioProfileLevel(value);
  296. return true;
  297. }
  298. catch (MP4Error* e) {
  299. PRINT_ERROR(e);
  300. delete e;
  301. }
  302. }
  303. return false;
  304. }
  305. extern "C" u_int8_t MP4GetGraphicsProfileLevel(MP4FileHandle hFile)
  306. {
  307. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  308. try {
  309. return ((MP4File*)hFile)->GetGraphicsProfileLevel();
  310. }
  311. catch (MP4Error* e) {
  312. PRINT_ERROR(e);
  313. delete e;
  314. }
  315. }
  316. return 0;
  317. }
  318. extern "C" bool MP4SetGraphicsProfileLevel(MP4FileHandle hFile, u_int8_t value)
  319. {
  320. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  321. try {
  322. ((MP4File*)hFile)->SetGraphicsProfileLevel(value);
  323. return true;
  324. }
  325. catch (MP4Error* e) {
  326. PRINT_ERROR(e);
  327. delete e;
  328. }
  329. }
  330. return false;
  331. }
  332. /* generic file properties */
  333. extern "C" u_int64_t MP4GetIntegerProperty(
  334. MP4FileHandle hFile, const char* propName)
  335. {
  336. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  337. try {
  338. return ((MP4File*)hFile)->GetIntegerProperty(propName);
  339. }
  340. catch (MP4Error* e) {
  341. PRINT_ERROR(e);
  342. delete e;
  343. }
  344. }
  345. return (u_int64_t)-1;
  346. }
  347. extern "C" float MP4GetFloatProperty(
  348. MP4FileHandle hFile, const char* propName)
  349. {
  350. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  351. try {
  352. return ((MP4File*)hFile)->GetFloatProperty(propName);
  353. }
  354. catch (MP4Error* e) {
  355. PRINT_ERROR(e);
  356. delete e;
  357. }
  358. }
  359. return NAN;
  360. }
  361. extern "C" const char* MP4GetStringProperty(
  362. MP4FileHandle hFile, const char* propName)
  363. {
  364. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  365. try {
  366. return ((MP4File*)hFile)->GetStringProperty(propName);
  367. }
  368. catch (MP4Error* e) {
  369. PRINT_ERROR(e);
  370. delete e;
  371. }
  372. }
  373. return NULL;
  374. }
  375. extern "C" void MP4GetBytesProperty(
  376. MP4FileHandle hFile, const char* propName, 
  377. u_int8_t** ppValue, u_int32_t* pValueSize)
  378. {
  379. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  380. try {
  381. ((MP4File*)hFile)->GetBytesProperty(propName, ppValue, pValueSize);
  382. return;
  383. }
  384. catch (MP4Error* e) {
  385. PRINT_ERROR(e);
  386. delete e;
  387. }
  388. }
  389. *ppValue = NULL;
  390. *pValueSize = 0;
  391. return;
  392. }
  393. extern "C" bool MP4SetIntegerProperty(
  394. MP4FileHandle hFile, const char* propName, int64_t value)
  395. {
  396. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  397. try {
  398. ((MP4File*)hFile)->SetIntegerProperty(propName, value);
  399. return true;
  400. }
  401. catch (MP4Error* e) {
  402. PRINT_ERROR(e);
  403. delete e;
  404. }
  405. }
  406. return false;
  407. }
  408. extern "C" bool MP4SetFloatProperty(
  409. MP4FileHandle hFile, const char* propName, float value)
  410. {
  411. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  412. try {
  413. ((MP4File*)hFile)->SetFloatProperty(propName, value);
  414. return true;
  415. }
  416. catch (MP4Error* e) {
  417. PRINT_ERROR(e);
  418. delete e;
  419. }
  420. }
  421. return false;
  422. }
  423. extern "C" bool MP4SetStringProperty(
  424. MP4FileHandle hFile, const char* propName, const char* value)
  425. {
  426. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  427. try {
  428. ((MP4File*)hFile)->SetStringProperty(propName, value);
  429. return true;
  430. }
  431. catch (MP4Error* e) {
  432. PRINT_ERROR(e);
  433. delete e;
  434. }
  435. }
  436. return false;
  437. }
  438. extern "C" bool MP4SetBytesProperty(
  439. MP4FileHandle hFile, const char* propName, 
  440. const u_int8_t* pValue, u_int32_t valueSize)
  441. {
  442. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  443. try {
  444. ((MP4File*)hFile)->SetBytesProperty(propName, pValue, valueSize);
  445. return true;
  446. }
  447. catch (MP4Error* e) {
  448. PRINT_ERROR(e);
  449. delete e;
  450. }
  451. }
  452. return false;
  453. }
  454. /* track operations */
  455. extern "C" MP4TrackId MP4AddTrack(
  456. MP4FileHandle hFile, const char* type)
  457. {
  458. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  459. try {
  460. return ((MP4File*)hFile)->AddSystemsTrack(type);
  461. }
  462. catch (MP4Error* e) {
  463. PRINT_ERROR(e);
  464. delete e;
  465. }
  466. }
  467. return MP4_INVALID_TRACK_ID;
  468. }
  469. extern "C" MP4TrackId MP4AddSystemsTrack(
  470. MP4FileHandle hFile, const char* type)
  471. {
  472. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  473. try {
  474. return ((MP4File*)hFile)->AddSystemsTrack(type);
  475. }
  476. catch (MP4Error* e) {
  477. PRINT_ERROR(e);
  478. delete e;
  479. }
  480. }
  481. return MP4_INVALID_TRACK_ID;
  482. }
  483. extern "C" MP4TrackId MP4AddODTrack(MP4FileHandle hFile)
  484. {
  485. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  486. try {
  487. return ((MP4File*)hFile)->AddODTrack();
  488. }
  489. catch (MP4Error* e) {
  490. PRINT_ERROR(e);
  491. delete e;
  492. }
  493. }
  494. return MP4_INVALID_TRACK_ID;
  495. }
  496. extern "C" MP4TrackId MP4AddSceneTrack(MP4FileHandle hFile)
  497. {
  498. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  499. try {
  500. return ((MP4File*)hFile)->AddSceneTrack();
  501. }
  502. catch (MP4Error* e) {
  503. PRINT_ERROR(e);
  504. delete e;
  505. }
  506. }
  507. return MP4_INVALID_TRACK_ID;
  508. }
  509. extern "C" MP4TrackId MP4AddAudioTrack(
  510. MP4FileHandle hFile, 
  511. u_int32_t timeScale, 
  512. MP4Duration sampleDuration, 
  513. u_int8_t audioType)
  514. {
  515. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  516. try {
  517. return ((MP4File*)hFile)->
  518. AddAudioTrack(timeScale, sampleDuration, audioType);
  519. }
  520. catch (MP4Error* e) {
  521. PRINT_ERROR(e);
  522. delete e;
  523. }
  524. }
  525. return MP4_INVALID_TRACK_ID;
  526. }
  527. extern "C" MP4TrackId MP4AddVideoTrack(
  528. MP4FileHandle hFile, 
  529. u_int32_t timeScale, 
  530. MP4Duration sampleDuration,
  531. u_int16_t width, 
  532. u_int16_t height, 
  533. u_int8_t videoType)
  534. {
  535. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  536. try {
  537. return ((MP4File*)hFile)->AddVideoTrack(
  538. timeScale, sampleDuration, width, height, videoType);
  539. }
  540. catch (MP4Error* e) {
  541. PRINT_ERROR(e);
  542. delete e;
  543. }
  544. }
  545. return MP4_INVALID_TRACK_ID;
  546. }
  547. extern "C" MP4TrackId MP4AddHintTrack(
  548. MP4FileHandle hFile, MP4TrackId refTrackId)
  549. {
  550. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  551. try {
  552. return ((MP4File*)hFile)->AddHintTrack(refTrackId);
  553. }
  554. catch (MP4Error* e) {
  555. PRINT_ERROR(e);
  556. delete e;
  557. }
  558. }
  559. return MP4_INVALID_TRACK_ID;
  560. }
  561. extern "C" MP4TrackId MP4CloneTrack(
  562. MP4FileHandle srcFile, 
  563. MP4TrackId srcTrackId,
  564. MP4FileHandle dstFile)
  565. {
  566. MP4TrackId dstTrackId = MP4_INVALID_TRACK_ID;
  567. if (dstFile == NULL) {
  568. dstFile = srcFile;
  569. }
  570. const char* trackType = 
  571. MP4GetTrackType(srcFile, srcTrackId);
  572. if (!trackType) {
  573. return dstTrackId;
  574. }
  575. if (MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
  576. dstTrackId = MP4AddVideoTrack(
  577. dstFile,
  578. MP4GetTrackTimeScale(srcFile, srcTrackId),
  579. MP4GetTrackFixedSampleDuration(srcFile, srcTrackId),
  580. MP4GetTrackVideoWidth(srcFile, srcTrackId),
  581. MP4GetTrackVideoHeight(srcFile, srcTrackId),
  582. MP4GetTrackVideoType(srcFile, srcTrackId));
  583. } else if (MP4_IS_AUDIO_TRACK_TYPE(trackType)) {
  584. dstTrackId = MP4AddAudioTrack(
  585. dstFile,
  586. MP4GetTrackTimeScale(srcFile, srcTrackId),
  587. MP4GetTrackFixedSampleDuration(srcFile, srcTrackId),
  588. MP4GetTrackAudioType(srcFile, srcTrackId));
  589. } else if (MP4_IS_OD_TRACK_TYPE(trackType)) {
  590. dstTrackId = MP4AddODTrack(dstFile);
  591. } else if (MP4_IS_SCENE_TRACK_TYPE(trackType)) {
  592. dstTrackId = MP4AddSceneTrack(dstFile);
  593. } else if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
  594. dstTrackId = MP4AddHintTrack(
  595. dstFile,
  596. MP4GetHintTrackReferenceTrackId(srcFile, srcTrackId));
  597. } else if (MP4_IS_SYSTEMS_TRACK_TYPE(trackType)) {
  598. dstTrackId = MP4AddSystemsTrack(dstFile, trackType);
  599. } else {
  600. dstTrackId = MP4AddTrack(dstFile, trackType);
  601. }
  602. if (dstTrackId == MP4_INVALID_TRACK_ID) {
  603. return dstTrackId;
  604. }
  605. MP4SetTrackTimeScale(
  606. dstFile, 
  607. dstTrackId,
  608. MP4GetTrackTimeScale(srcFile, srcTrackId));
  609. // copy track ES configuration
  610. u_int8_t* pConfig = NULL;
  611. u_int32_t configSize = 0;
  612. MP4GetTrackESConfiguration(
  613. srcFile, 
  614. srcTrackId,
  615. &pConfig,
  616. &configSize);
  617. MP4SetTrackESConfiguration(
  618. dstFile, 
  619. dstTrackId,
  620. pConfig,
  621. configSize);
  622. free(pConfig);
  623. if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
  624. // probably not exactly what is wanted
  625. // but caller can adjust later to fit their desires
  626. char* payloadName = NULL;
  627. u_int8_t payloadNumber;
  628. u_int16_t maxPayloadSize;
  629. MP4GetHintTrackRtpPayload(
  630. srcFile,
  631. srcTrackId,
  632. &payloadName,
  633. &payloadNumber,
  634. &maxPayloadSize);
  635. MP4SetHintTrackRtpPayload(
  636. dstFile,
  637. dstTrackId,
  638. payloadName,
  639. &payloadNumber,
  640. maxPayloadSize);
  641. MP4SetHintTrackSdp(
  642. dstFile,
  643. dstTrackId,
  644. MP4GetHintTrackSdp(srcFile, srcTrackId));
  645. }
  646. return dstTrackId;
  647. }
  648. extern "C" MP4TrackId MP4CopyTrack(
  649. MP4FileHandle srcFile, 
  650. MP4TrackId srcTrackId,
  651. MP4FileHandle dstFile, 
  652. bool applyEdits)
  653. {
  654. bool copySamples = true; // LATER allow false => reference samples
  655. MP4TrackId dstTrackId =
  656. MP4CloneTrack(srcFile, srcTrackId, dstFile);
  657. if (dstTrackId == MP4_INVALID_TRACK_ID) {
  658. return dstTrackId;
  659. }
  660. bool viaEdits =
  661. applyEdits && MP4GetTrackNumberOfEdits(srcFile, srcTrackId);
  662. MP4SampleId sampleId = 0;
  663. MP4SampleId numSamples = 
  664. MP4GetTrackNumberOfSamples(srcFile, srcTrackId);
  665. MP4Timestamp when = 0;
  666. MP4Duration editsDuration = 
  667. MP4GetTrackEditTotalDuration(srcFile, srcTrackId);
  668. while (true) {
  669. MP4Duration sampleDuration = MP4_INVALID_DURATION;
  670. if (viaEdits) {
  671. sampleId = MP4GetSampleIdFromEditTime(
  672. srcFile,
  673. srcTrackId,
  674. when,
  675. NULL,
  676. &sampleDuration);
  677. // in theory, this shouldn't happen
  678. if (sampleId == MP4_INVALID_SAMPLE_ID) {
  679. MP4DeleteTrack(dstFile, dstTrackId);
  680. return MP4_INVALID_TRACK_ID;
  681. }
  682. when += sampleDuration;
  683. if (when >= editsDuration) {
  684. break;
  685. }
  686. } else {
  687. sampleId++;
  688. if (sampleId > numSamples) {
  689. break;
  690. }
  691. }
  692. bool rc = false;
  693. if (copySamples) {
  694. rc = MP4CopySample(
  695. srcFile,
  696. srcTrackId,
  697. sampleId,
  698. dstFile,
  699. dstTrackId,
  700. sampleDuration);
  701. } else {
  702. rc = MP4ReferenceSample(
  703. srcFile,
  704. srcTrackId,
  705. sampleId,
  706. dstFile,
  707. dstTrackId,
  708. sampleDuration);
  709. }
  710. if (!rc) {
  711. MP4DeleteTrack(dstFile, dstTrackId);
  712. return MP4_INVALID_TRACK_ID;
  713. }
  714. }
  715. return dstTrackId;
  716. }
  717. extern "C" bool MP4DeleteTrack(
  718. MP4FileHandle hFile, 
  719. MP4TrackId trackId)
  720. {
  721. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  722. try {
  723. ((MP4File*)hFile)->DeleteTrack(trackId);
  724. return true;
  725. }
  726. catch (MP4Error* e) {
  727. PRINT_ERROR(e);
  728. delete e;
  729. }
  730. }
  731. return false;
  732. }
  733. extern "C" u_int32_t MP4GetNumberOfTracks(
  734. MP4FileHandle hFile, 
  735. const char* type,
  736. u_int8_t subType)
  737. {
  738. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  739. try {
  740. return ((MP4File*)hFile)->GetNumberOfTracks(type, subType);
  741. }
  742. catch (MP4Error* e) {
  743. PRINT_ERROR(e);
  744. delete e;
  745. }
  746. }
  747. return 0;
  748. }
  749. extern "C" MP4TrackId MP4FindTrackId(
  750. MP4FileHandle hFile, 
  751. u_int16_t index, 
  752. const char* type,
  753. u_int8_t subType)
  754. {
  755. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  756. try {
  757. return ((MP4File*)hFile)->FindTrackId(index, type, subType);
  758. }
  759. catch (MP4Error* e) {
  760. PRINT_ERROR(e);
  761. delete e;
  762. }
  763. }
  764. return MP4_INVALID_TRACK_ID;
  765. }
  766. extern "C" u_int16_t MP4FindTrackIndex(
  767. MP4FileHandle hFile, MP4TrackId trackId)
  768. {
  769. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  770. try {
  771. return ((MP4File*)hFile)->FindTrackIndex(trackId);
  772. }
  773. catch (MP4Error* e) {
  774. PRINT_ERROR(e);
  775. delete e;
  776. }
  777. }
  778. return (u_int16_t)-1;
  779. }
  780. /* specific track properties */
  781. extern "C" const char* MP4GetTrackType(
  782. MP4FileHandle hFile, MP4TrackId trackId)
  783. {
  784. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  785. try {
  786. return ((MP4File*)hFile)->GetTrackType(trackId);
  787. }
  788. catch (MP4Error* e) {
  789. PRINT_ERROR(e);
  790. delete e;
  791. }
  792. }
  793. return NULL;
  794. }
  795. extern "C" MP4Duration MP4GetTrackDuration(
  796. MP4FileHandle hFile, MP4TrackId trackId)
  797. {
  798. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  799. try {
  800. return ((MP4File*)hFile)->GetTrackDuration(trackId);
  801. }
  802. catch (MP4Error* e) {
  803. PRINT_ERROR(e);
  804. delete e;
  805. }
  806. }
  807. return MP4_INVALID_DURATION;
  808. }
  809. extern "C" u_int32_t MP4GetTrackTimeScale(
  810. MP4FileHandle hFile, MP4TrackId trackId)
  811. {
  812. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  813. try {
  814. return ((MP4File*)hFile)->GetTrackTimeScale(trackId);
  815. }
  816. catch (MP4Error* e) {
  817. PRINT_ERROR(e);
  818. delete e;
  819. }
  820. }
  821. return 0;
  822. }
  823. extern "C" bool MP4SetTrackTimeScale(
  824. MP4FileHandle hFile, MP4TrackId trackId, u_int32_t value)
  825. {
  826. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  827. try {
  828. ((MP4File*)hFile)->SetTrackTimeScale(trackId, value);
  829. return true;
  830. }
  831. catch (MP4Error* e) {
  832. PRINT_ERROR(e);
  833. delete e;
  834. }
  835. }
  836. return false;
  837. }
  838. extern "C" u_int8_t MP4GetTrackAudioType(
  839. MP4FileHandle hFile, MP4TrackId trackId)
  840. {
  841. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  842. try {
  843. return ((MP4File*)hFile)->GetTrackAudioType(trackId);
  844. }
  845. catch (MP4Error* e) {
  846. PRINT_ERROR(e);
  847. delete e;
  848. }
  849. }
  850. return MP4_INVALID_AUDIO_TYPE;
  851. }
  852. extern "C" u_int8_t MP4GetTrackAudioMpeg4Type(
  853. MP4FileHandle hFile, MP4TrackId trackId)
  854. {
  855. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  856. try {
  857. return ((MP4File*)hFile)->GetTrackAudioMpeg4Type(trackId);
  858. }
  859. catch (MP4Error* e) {
  860. PRINT_ERROR(e);
  861. delete e;
  862. }
  863. }
  864. return MP4_MPEG4_INVALID_AUDIO_TYPE;
  865. }
  866. extern "C" u_int8_t MP4GetTrackVideoType(
  867. MP4FileHandle hFile, MP4TrackId trackId)
  868. {
  869. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  870. try {
  871. return ((MP4File*)hFile)->GetTrackVideoType(trackId);
  872. }
  873. catch (MP4Error* e) {
  874. PRINT_ERROR(e);
  875. delete e;
  876. }
  877. }
  878. return MP4_INVALID_VIDEO_TYPE;
  879. }
  880. extern "C" MP4Duration MP4GetTrackFixedSampleDuration(
  881. MP4FileHandle hFile, MP4TrackId trackId)
  882. {
  883. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  884. try {
  885. return ((MP4File*)hFile)->GetTrackFixedSampleDuration(trackId);
  886. }
  887. catch (MP4Error* e) {
  888. PRINT_ERROR(e);
  889. delete e;
  890. }
  891. }
  892. return MP4_INVALID_DURATION;
  893. }
  894. extern "C" u_int32_t MP4GetTrackBitRate(
  895. MP4FileHandle hFile, MP4TrackId trackId)
  896. {
  897. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  898. try {
  899. return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
  900. "mdia.minf.stbl.stsd.*.esds.decConfigDescr.avgBitrate");
  901. }
  902. catch (MP4Error* e) {
  903. PRINT_ERROR(e);
  904. delete e;
  905. }
  906. }
  907. return 0;
  908. }
  909. extern "C" void MP4GetTrackESConfiguration(
  910. MP4FileHandle hFile, MP4TrackId trackId, 
  911. u_int8_t** ppConfig, u_int32_t* pConfigSize)
  912. {
  913. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  914. try {
  915. ((MP4File*)hFile)->GetTrackESConfiguration(
  916. trackId, ppConfig, pConfigSize);
  917. return;
  918. }
  919. catch (MP4Error* e) {
  920. PRINT_ERROR(e);
  921. delete e;
  922. }
  923. }
  924. *ppConfig = NULL;
  925. *pConfigSize = 0;
  926. return;
  927. }
  928. extern "C" bool MP4SetTrackESConfiguration(
  929. MP4FileHandle hFile, MP4TrackId trackId, 
  930. const u_int8_t* pConfig, u_int32_t configSize)
  931. {
  932. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  933. try {
  934. ((MP4File*)hFile)->SetTrackESConfiguration(
  935. trackId, pConfig, configSize);
  936. return true;
  937. }
  938. catch (MP4Error* e) {
  939. PRINT_ERROR(e);
  940. delete e;
  941. }
  942. }
  943. return false;
  944. }
  945. extern "C" MP4SampleId MP4GetTrackNumberOfSamples(
  946. MP4FileHandle hFile, MP4TrackId trackId)
  947. {
  948. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  949. try {
  950. return ((MP4File*)hFile)->GetTrackNumberOfSamples(trackId);
  951. }
  952. catch (MP4Error* e) {
  953. PRINT_ERROR(e);
  954. delete e;
  955. }
  956. }
  957. return 0;
  958. }
  959. extern "C" u_int16_t MP4GetTrackVideoWidth(
  960. MP4FileHandle hFile, MP4TrackId trackId)
  961. {
  962. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  963. try {
  964. return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
  965. "mdia.minf.stbl.stsd.mp4v.width");
  966. }
  967. catch (MP4Error* e) {
  968. PRINT_ERROR(e);
  969. delete e;
  970. }
  971. }
  972. return 0;
  973. }
  974. extern "C" u_int16_t MP4GetTrackVideoHeight(
  975. MP4FileHandle hFile, MP4TrackId trackId)
  976. {
  977. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  978. try {
  979. return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
  980. "mdia.minf.stbl.stsd.mp4v.height");
  981. }
  982. catch (MP4Error* e) {
  983. PRINT_ERROR(e);
  984. delete e;
  985. }
  986. }
  987. return 0;
  988. }
  989. extern "C" float MP4GetTrackVideoFrameRate(
  990. MP4FileHandle hFile, MP4TrackId trackId)
  991. {
  992. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  993. try {
  994. return ((MP4File*)hFile)->GetTrackVideoFrameRate(trackId);
  995. }
  996. catch (MP4Error* e) {
  997. PRINT_ERROR(e);
  998. delete e;
  999. }
  1000. }
  1001. return 0.0;
  1002. }
  1003. /* generic track properties */
  1004. extern "C" u_int64_t MP4GetTrackIntegerProperty(
  1005. MP4FileHandle hFile, MP4TrackId trackId, 
  1006. const char* propName)
  1007. {
  1008. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1009. try {
  1010. return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId, 
  1011. propName);
  1012. }
  1013. catch (MP4Error* e) {
  1014. PRINT_ERROR(e);
  1015. delete e;
  1016. }
  1017. }
  1018. return (u_int64_t)-1;
  1019. }
  1020. extern "C" float MP4GetTrackFloatProperty(
  1021. MP4FileHandle hFile, MP4TrackId trackId, 
  1022. const char* propName)
  1023. {
  1024. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1025. try {
  1026. return ((MP4File*)hFile)->GetTrackFloatProperty(trackId, propName);
  1027. }
  1028. catch (MP4Error* e) {
  1029. PRINT_ERROR(e);
  1030. delete e;
  1031. }
  1032. }
  1033. return NAN;
  1034. }
  1035. extern "C" const char* MP4GetTrackStringProperty(
  1036. MP4FileHandle hFile, MP4TrackId trackId, 
  1037. const char* propName)
  1038. {
  1039. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1040. try {
  1041. return ((MP4File*)hFile)->GetTrackStringProperty(trackId, propName);
  1042. }
  1043. catch (MP4Error* e) {
  1044. PRINT_ERROR(e);
  1045. delete e;
  1046. }
  1047. }
  1048. return NULL;
  1049. }
  1050. extern "C" void MP4GetTrackBytesProperty(
  1051. MP4FileHandle hFile, MP4TrackId trackId, const char* propName, 
  1052. u_int8_t** ppValue, u_int32_t* pValueSize)
  1053. {
  1054. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1055. try {
  1056. ((MP4File*)hFile)->GetTrackBytesProperty(
  1057. trackId, propName, ppValue, pValueSize);
  1058. return;
  1059. }
  1060. catch (MP4Error* e) {
  1061. PRINT_ERROR(e);
  1062. delete e;
  1063. }
  1064. }
  1065. *ppValue = NULL;
  1066. *pValueSize = 0;
  1067. return;
  1068. }
  1069. extern "C" bool MP4SetTrackIntegerProperty(
  1070. MP4FileHandle hFile, MP4TrackId trackId, 
  1071. const char* propName, int64_t value)
  1072. {
  1073. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1074. try {
  1075. ((MP4File*)hFile)->SetTrackIntegerProperty(trackId, 
  1076. propName, value);
  1077. return true;
  1078. }
  1079. catch (MP4Error* e) {
  1080. PRINT_ERROR(e);
  1081. delete e;
  1082. }
  1083. }
  1084. return false;
  1085. }
  1086. extern "C" bool MP4SetTrackFloatProperty(
  1087. MP4FileHandle hFile, MP4TrackId trackId, 
  1088. const char* propName, float value)
  1089. {
  1090. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1091. try {
  1092. ((MP4File*)hFile)->SetTrackFloatProperty(trackId, propName, value);
  1093. return true;
  1094. }
  1095. catch (MP4Error* e) {
  1096. PRINT_ERROR(e);
  1097. delete e;
  1098. }
  1099. }
  1100. return false;
  1101. }
  1102. extern "C" bool MP4SetTrackStringProperty(
  1103. MP4FileHandle hFile, MP4TrackId trackId, 
  1104. const char* propName, const char* value)
  1105. {
  1106. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1107. try {
  1108. ((MP4File*)hFile)->SetTrackStringProperty(trackId, propName, value);
  1109. return true;
  1110. }
  1111. catch (MP4Error* e) {
  1112. PRINT_ERROR(e);
  1113. delete e;
  1114. }
  1115. }
  1116. return false;
  1117. }
  1118. extern "C" bool MP4SetTrackBytesProperty(
  1119. MP4FileHandle hFile, MP4TrackId trackId, 
  1120. const char* propName, const u_int8_t* pValue, u_int32_t valueSize)
  1121. {
  1122. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1123. try {
  1124. ((MP4File*)hFile)->SetTrackBytesProperty(
  1125. trackId, propName, pValue, valueSize);
  1126. return true;
  1127. }
  1128. catch (MP4Error* e) {
  1129. PRINT_ERROR(e);
  1130. delete e;
  1131. }
  1132. }
  1133. return false;
  1134. }
  1135. /* sample operations */
  1136. extern "C" bool MP4ReadSample(
  1137. /* input parameters */
  1138. MP4FileHandle hFile,
  1139. MP4TrackId trackId, 
  1140. MP4SampleId sampleId,
  1141. /* output parameters */
  1142. u_int8_t** ppBytes, 
  1143. u_int32_t* pNumBytes, 
  1144. MP4Timestamp* pStartTime, 
  1145. MP4Duration* pDuration,
  1146. MP4Duration* pRenderingOffset, 
  1147. bool* pIsSyncSample)
  1148. {
  1149. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1150. try {
  1151. ((MP4File*)hFile)->ReadSample(
  1152. trackId, 
  1153. sampleId, 
  1154. ppBytes, 
  1155. pNumBytes, 
  1156. pStartTime, 
  1157. pDuration, 
  1158. pRenderingOffset, 
  1159. pIsSyncSample);
  1160. return true;
  1161. }
  1162. catch (MP4Error* e) {
  1163. PRINT_ERROR(e);
  1164. delete e;
  1165. }
  1166. }
  1167. *pNumBytes = 0;
  1168. return false;
  1169. }
  1170. extern "C" bool MP4ReadSampleFromTime(
  1171. /* input parameters */
  1172. MP4FileHandle hFile,
  1173. MP4TrackId trackId, 
  1174. MP4Timestamp when,
  1175. /* output parameters */
  1176. u_int8_t** ppBytes, 
  1177. u_int32_t* pNumBytes, 
  1178. MP4Timestamp* pStartTime, 
  1179. MP4Duration* pDuration,
  1180. MP4Duration* pRenderingOffset, 
  1181. bool* pIsSyncSample)
  1182. {
  1183. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1184. try {
  1185. MP4SampleId sampleId = 
  1186. ((MP4File*)hFile)->GetSampleIdFromTime(
  1187. trackId, when, false);
  1188. ((MP4File*)hFile)->ReadSample(
  1189. trackId, 
  1190. sampleId, 
  1191. ppBytes, 
  1192. pNumBytes, 
  1193. pStartTime, 
  1194. pDuration, 
  1195. pRenderingOffset, 
  1196. pIsSyncSample);
  1197. return true;
  1198. }
  1199. catch (MP4Error* e) {
  1200. PRINT_ERROR(e);
  1201. delete e;
  1202. }
  1203. }
  1204. *pNumBytes = 0;
  1205. return false;
  1206. }
  1207. extern "C" bool MP4WriteSample(
  1208. MP4FileHandle hFile,
  1209. MP4TrackId trackId,
  1210. u_int8_t* pBytes, 
  1211. u_int32_t numBytes,
  1212. MP4Duration duration,
  1213. MP4Duration renderingOffset, 
  1214. bool isSyncSample)
  1215. {
  1216. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1217. try {
  1218. ((MP4File*)hFile)->WriteSample(
  1219. trackId, 
  1220. pBytes, 
  1221. numBytes, 
  1222. duration, 
  1223. renderingOffset, 
  1224. isSyncSample);
  1225. return true;
  1226. }
  1227. catch (MP4Error* e) {
  1228. PRINT_ERROR(e);
  1229. delete e;
  1230. }
  1231. }
  1232. return false;
  1233. }
  1234. extern "C" bool MP4CopySample(
  1235. MP4FileHandle srcFile,
  1236. MP4TrackId srcTrackId, 
  1237. MP4SampleId srcSampleId,
  1238. MP4FileHandle dstFile,
  1239. MP4TrackId dstTrackId,
  1240. MP4Duration dstSampleDuration)
  1241. {
  1242. bool rc;
  1243. u_int8_t* pBytes = NULL; 
  1244. u_int32_t numBytes = 0;
  1245. MP4Duration sampleDuration;
  1246. MP4Duration renderingOffset;
  1247. bool isSyncSample;
  1248. // Note: we leave it up to the caller to ensure that the
  1249. // source and destination tracks are compatible.
  1250. // i.e. copying audio samples into a video track 
  1251. // is unlikely to do anything useful
  1252. rc = MP4ReadSample(
  1253. srcFile,
  1254. srcTrackId,
  1255. srcSampleId,
  1256. &pBytes,
  1257. &numBytes,
  1258. NULL,
  1259. &sampleDuration,
  1260. &renderingOffset,
  1261. &isSyncSample);
  1262. if (!rc) {
  1263. return false;
  1264. }
  1265. if (dstFile == MP4_INVALID_FILE_HANDLE) {
  1266. dstFile = srcFile;
  1267. }
  1268. if (dstTrackId == MP4_INVALID_TRACK_ID) {
  1269. dstTrackId = srcTrackId;
  1270. }
  1271. if (dstSampleDuration != MP4_INVALID_DURATION) {
  1272. sampleDuration = dstSampleDuration;
  1273. }
  1274. rc = MP4WriteSample(
  1275. dstFile,
  1276. dstTrackId,
  1277. pBytes,
  1278. numBytes,
  1279. sampleDuration,
  1280. renderingOffset,
  1281. isSyncSample);
  1282. free(pBytes);
  1283. return rc;
  1284. }
  1285. extern "C" bool MP4ReferenceSample(
  1286. MP4FileHandle srcFile,
  1287. MP4TrackId srcTrackId, 
  1288. MP4SampleId srcSampleId,
  1289. MP4FileHandle dstFile,
  1290. MP4TrackId dstTrackId,
  1291. MP4Duration dstSampleDuration)
  1292. {
  1293. // LATER Not yet implemented
  1294. return false;
  1295. }
  1296. extern "C" u_int32_t MP4GetSampleSize(
  1297. MP4FileHandle hFile,
  1298. MP4TrackId trackId, 
  1299. MP4SampleId sampleId)
  1300. {
  1301. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1302. try {
  1303. return ((MP4File*)hFile)->GetSampleSize(
  1304. trackId, sampleId);
  1305. }
  1306. catch (MP4Error* e) {
  1307. PRINT_ERROR(e);
  1308. delete e;
  1309. }
  1310. }
  1311. return 0;
  1312. }
  1313. extern "C" u_int32_t MP4GetTrackMaxSampleSize(
  1314. MP4FileHandle hFile,
  1315. MP4TrackId trackId)
  1316. {
  1317. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1318. try {
  1319. return ((MP4File*)hFile)->GetTrackMaxSampleSize(trackId);
  1320. }
  1321. catch (MP4Error* e) {
  1322. PRINT_ERROR(e);
  1323. delete e;
  1324. }
  1325. }
  1326. return 0;
  1327. }
  1328. extern "C" MP4SampleId MP4GetSampleIdFromTime(
  1329. MP4FileHandle hFile,
  1330. MP4TrackId trackId, 
  1331. MP4Timestamp when, 
  1332. bool wantSyncSample)
  1333. {
  1334. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1335. try {
  1336. return ((MP4File*)hFile)->GetSampleIdFromTime(
  1337. trackId, when, wantSyncSample);
  1338. }
  1339. catch (MP4Error* e) {
  1340. PRINT_ERROR(e);
  1341. delete e;
  1342. }
  1343. }
  1344. return MP4_INVALID_SAMPLE_ID;
  1345. }
  1346. extern "C" MP4Timestamp MP4GetSampleTime(
  1347. MP4FileHandle hFile,
  1348. MP4TrackId trackId, 
  1349. MP4SampleId sampleId)
  1350. {
  1351. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1352. try {
  1353. return ((MP4File*)hFile)->GetSampleTime(
  1354. trackId, sampleId);
  1355. }
  1356. catch (MP4Error* e) {
  1357. PRINT_ERROR(e);
  1358. delete e;
  1359. }
  1360. }
  1361. return MP4_INVALID_TIMESTAMP;
  1362. }
  1363. extern "C" MP4Duration MP4GetSampleDuration(
  1364. MP4FileHandle hFile,
  1365. MP4TrackId trackId, 
  1366. MP4SampleId sampleId)
  1367. {
  1368. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1369. try {
  1370. return ((MP4File*)hFile)->GetSampleDuration(
  1371. trackId, sampleId);
  1372. }
  1373. catch (MP4Error* e) {
  1374. PRINT_ERROR(e);
  1375. delete e;
  1376. }
  1377. }
  1378. return MP4_INVALID_DURATION;
  1379. }
  1380. extern "C" MP4Duration MP4GetSampleRenderingOffset(
  1381. MP4FileHandle hFile,
  1382. MP4TrackId trackId, 
  1383. MP4SampleId sampleId)
  1384. {
  1385. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1386. try {
  1387. return ((MP4File*)hFile)->GetSampleRenderingOffset(
  1388. trackId, sampleId);
  1389. }
  1390. catch (MP4Error* e) {
  1391. PRINT_ERROR(e);
  1392. delete e;
  1393. }
  1394. }
  1395. return MP4_INVALID_DURATION;
  1396. }
  1397. extern "C" bool MP4SetSampleRenderingOffset(
  1398. MP4FileHandle hFile,
  1399. MP4TrackId trackId, 
  1400. MP4SampleId sampleId,
  1401. MP4Duration renderingOffset)
  1402. {
  1403. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1404. try {
  1405. ((MP4File*)hFile)->SetSampleRenderingOffset(
  1406. trackId, sampleId, renderingOffset);
  1407. return true;
  1408. }
  1409. catch (MP4Error* e) {
  1410. PRINT_ERROR(e);
  1411. delete e;
  1412. }
  1413. }
  1414. return false;
  1415. }
  1416. extern "C" int8_t MP4GetSampleSync(
  1417. MP4FileHandle hFile,
  1418. MP4TrackId trackId, 
  1419. MP4SampleId sampleId)
  1420. {
  1421. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1422. try {
  1423. return ((MP4File*)hFile)->GetSampleSync(
  1424. trackId, sampleId);
  1425. }
  1426. catch (MP4Error* e) {
  1427. PRINT_ERROR(e);
  1428. delete e;
  1429. }
  1430. }
  1431. return -1;
  1432. }
  1433. extern "C" u_int64_t MP4ConvertFromMovieDuration(
  1434. MP4FileHandle hFile,
  1435. MP4Duration duration,
  1436. u_int32_t timeScale)
  1437. {
  1438. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1439. try {
  1440. return ((MP4File*)hFile)->ConvertFromMovieDuration(
  1441. duration, timeScale);
  1442. }
  1443. catch (MP4Error* e) {
  1444. PRINT_ERROR(e);
  1445. delete e;
  1446. }
  1447. }
  1448. return (u_int64_t)MP4_INVALID_DURATION;
  1449. }
  1450. extern "C" u_int64_t MP4ConvertFromTrackTimestamp(
  1451. MP4FileHandle hFile,
  1452. MP4TrackId trackId, 
  1453. MP4Timestamp timeStamp,
  1454. u_int32_t timeScale)
  1455. {
  1456. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1457. try {
  1458. return ((MP4File*)hFile)->ConvertFromTrackTimestamp(
  1459. trackId, timeStamp, timeScale);
  1460. }
  1461. catch (MP4Error* e) {
  1462. PRINT_ERROR(e);
  1463. delete e;
  1464. }
  1465. }
  1466. return (u_int64_t)MP4_INVALID_TIMESTAMP;
  1467. }
  1468. extern "C" MP4Timestamp MP4ConvertToTrackTimestamp(
  1469. MP4FileHandle hFile,
  1470. MP4TrackId trackId, 
  1471. u_int64_t timeStamp,
  1472. u_int32_t timeScale)
  1473. {
  1474. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1475. try {
  1476. return ((MP4File*)hFile)->ConvertToTrackTimestamp(
  1477. trackId, timeStamp, timeScale);
  1478. }
  1479. catch (MP4Error* e) {
  1480. PRINT_ERROR(e);
  1481. delete e;
  1482. }
  1483. }
  1484. return MP4_INVALID_TIMESTAMP;
  1485. }
  1486. extern "C" u_int64_t MP4ConvertFromTrackDuration(
  1487. MP4FileHandle hFile,
  1488. MP4TrackId trackId, 
  1489. MP4Duration duration,
  1490. u_int32_t timeScale)
  1491. {
  1492. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1493. try {
  1494. return ((MP4File*)hFile)->ConvertFromTrackDuration(
  1495. trackId, duration, timeScale);
  1496. }
  1497. catch (MP4Error* e) {
  1498. PRINT_ERROR(e);
  1499. delete e;
  1500. }
  1501. }
  1502. return (u_int64_t)MP4_INVALID_DURATION;
  1503. }
  1504. extern "C" MP4Duration MP4ConvertToTrackDuration(
  1505. MP4FileHandle hFile,
  1506. MP4TrackId trackId, 
  1507. u_int64_t duration,
  1508. u_int32_t timeScale)
  1509. {
  1510. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1511. try {
  1512. return ((MP4File*)hFile)->ConvertToTrackDuration(
  1513. trackId, duration, timeScale);
  1514. }
  1515. catch (MP4Error* e) {
  1516. PRINT_ERROR(e);
  1517. delete e;
  1518. }
  1519. }
  1520. return MP4_INVALID_DURATION;
  1521. }
  1522. extern "C" bool MP4GetHintTrackRtpPayload(
  1523. MP4FileHandle hFile,
  1524. MP4TrackId hintTrackId,
  1525. char** ppPayloadName,
  1526. u_int8_t* pPayloadNumber,
  1527. u_int16_t* pMaxPayloadSize)
  1528. {
  1529. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1530. try {
  1531. ((MP4File*)hFile)->GetHintTrackRtpPayload(
  1532. hintTrackId, ppPayloadName, pPayloadNumber, pMaxPayloadSize);
  1533. return true;
  1534. }
  1535. catch (MP4Error* e) {
  1536. PRINT_ERROR(e);
  1537. delete e;
  1538. }
  1539. }
  1540. return false;
  1541. }
  1542. extern "C" bool MP4SetHintTrackRtpPayload(
  1543. MP4FileHandle hFile,
  1544. MP4TrackId hintTrackId,
  1545. const char* pPayloadName,
  1546. u_int8_t* pPayloadNumber,
  1547. u_int16_t maxPayloadSize)
  1548. {
  1549. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1550. try {
  1551. ((MP4File*)hFile)->SetHintTrackRtpPayload(
  1552. hintTrackId, pPayloadName, pPayloadNumber, maxPayloadSize);
  1553. return true;
  1554. }
  1555. catch (MP4Error* e) {
  1556. PRINT_ERROR(e);
  1557. delete e;
  1558. }
  1559. }
  1560. return false;
  1561. }
  1562. extern "C" const char* MP4GetSessionSdp(
  1563. MP4FileHandle hFile)
  1564. {
  1565. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1566. try {
  1567. return ((MP4File*)hFile)->GetSessionSdp();
  1568. }
  1569. catch (MP4Error* e) {
  1570. PRINT_ERROR(e);
  1571. delete e;
  1572. }
  1573. }
  1574. return NULL;
  1575. }
  1576. extern "C" bool MP4SetSessionSdp(
  1577. MP4FileHandle hFile,
  1578. const char* sdpString)
  1579. {
  1580. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1581. try {
  1582. ((MP4File*)hFile)->SetSessionSdp(sdpString);
  1583. return true;
  1584. }
  1585. catch (MP4Error* e) {
  1586. PRINT_ERROR(e);
  1587. delete e;
  1588. }
  1589. }
  1590. return false;
  1591. }
  1592. extern "C" bool MP4AppendSessionSdp(
  1593. MP4FileHandle hFile,
  1594. const char* sdpString)
  1595. {
  1596. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1597. try {
  1598. ((MP4File*)hFile)->AppendSessionSdp(sdpString);
  1599. return true;
  1600. }
  1601. catch (MP4Error* e) {
  1602. PRINT_ERROR(e);
  1603. delete e;
  1604. }
  1605. }
  1606. return false;
  1607. }
  1608. extern "C" const char* MP4GetHintTrackSdp(
  1609. MP4FileHandle hFile,
  1610. MP4TrackId hintTrackId)
  1611. {
  1612. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1613. try {
  1614. return ((MP4File*)hFile)->GetHintTrackSdp(hintTrackId);
  1615. }
  1616. catch (MP4Error* e) {
  1617. PRINT_ERROR(e);
  1618. delete e;
  1619. }
  1620. }
  1621. return NULL;
  1622. }
  1623. extern "C" bool MP4SetHintTrackSdp(
  1624. MP4FileHandle hFile,
  1625. MP4TrackId hintTrackId,
  1626. const char* sdpString)
  1627. {
  1628. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1629. try {
  1630. ((MP4File*)hFile)->SetHintTrackSdp(hintTrackId, sdpString);
  1631. return true;
  1632. }
  1633. catch (MP4Error* e) {
  1634. PRINT_ERROR(e);
  1635. delete e;
  1636. }
  1637. }
  1638. return false;
  1639. }
  1640. extern "C" bool MP4AppendHintTrackSdp(
  1641. MP4FileHandle hFile,
  1642. MP4TrackId hintTrackId,
  1643. const char* sdpString)
  1644. {
  1645. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1646. try {
  1647. ((MP4File*)hFile)->AppendHintTrackSdp(hintTrackId, sdpString);
  1648. return true;
  1649. }
  1650. catch (MP4Error* e) {
  1651. PRINT_ERROR(e);
  1652. delete e;
  1653. }
  1654. }
  1655. return false;
  1656. }
  1657. extern "C" MP4TrackId MP4GetHintTrackReferenceTrackId(
  1658. MP4FileHandle hFile,
  1659. MP4TrackId hintTrackId)
  1660. {
  1661. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1662. try {
  1663. return ((MP4File*)hFile)->
  1664. GetHintTrackReferenceTrackId(hintTrackId);
  1665. }
  1666. catch (MP4Error* e) {
  1667. PRINT_ERROR(e);
  1668. delete e;
  1669. }
  1670. }
  1671. return MP4_INVALID_TRACK_ID;
  1672. }
  1673. extern "C" bool MP4ReadRtpHint(
  1674. MP4FileHandle hFile,
  1675. MP4TrackId hintTrackId,
  1676. MP4SampleId hintSampleId,
  1677. u_int16_t* pNumPackets)
  1678. {
  1679. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1680. try {
  1681. ((MP4File*)hFile)->ReadRtpHint(
  1682. hintTrackId, hintSampleId, pNumPackets);
  1683. return true;
  1684. }
  1685. catch (MP4Error* e) {
  1686. PRINT_ERROR(e);
  1687. delete e;
  1688. }
  1689. }
  1690. return false;
  1691. }
  1692. extern "C" u_int16_t MP4GetRtpHintNumberOfPackets(
  1693. MP4FileHandle hFile,
  1694. MP4TrackId hintTrackId)
  1695. {
  1696. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1697. try {
  1698. return ((MP4File*)hFile)->GetRtpHintNumberOfPackets(hintTrackId);
  1699. }
  1700. catch (MP4Error* e) {
  1701. PRINT_ERROR(e);
  1702. delete e;
  1703. }
  1704. }
  1705. return 0;
  1706. }
  1707. extern "C" int8_t MP4GetRtpPacketBFrame(
  1708. MP4FileHandle hFile,
  1709. MP4TrackId hintTrackId,
  1710. u_int16_t packetIndex)
  1711. {
  1712. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1713. try {
  1714. return ((MP4File*)hFile)->
  1715. GetRtpPacketBFrame(hintTrackId, packetIndex);
  1716. }
  1717. catch (MP4Error* e) {
  1718. PRINT_ERROR(e);
  1719. delete e;
  1720. }
  1721. }
  1722. return -1;
  1723. }
  1724. extern "C" int32_t MP4GetRtpPacketTransmitOffset(
  1725. MP4FileHandle hFile,
  1726. MP4TrackId hintTrackId,
  1727. u_int16_t packetIndex)
  1728. {
  1729. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1730. try {
  1731. return ((MP4File*)hFile)->
  1732. GetRtpPacketTransmitOffset(hintTrackId, packetIndex);
  1733. }
  1734. catch (MP4Error* e) {
  1735. PRINT_ERROR(e);
  1736. delete e;
  1737. }
  1738. }
  1739. return 0;
  1740. }
  1741. extern "C" bool MP4ReadRtpPacket(
  1742. MP4FileHandle hFile,
  1743. MP4TrackId hintTrackId,
  1744. u_int16_t packetIndex,
  1745. u_int8_t** ppBytes, 
  1746. u_int32_t* pNumBytes,
  1747. u_int32_t ssrc,
  1748. bool includeHeader,
  1749. bool includePayload)
  1750. {
  1751. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1752. try {
  1753. ((MP4File*)hFile)->ReadRtpPacket(
  1754. hintTrackId, packetIndex, 
  1755. ppBytes, pNumBytes, 
  1756. ssrc, includeHeader, includePayload);
  1757. return true;
  1758. }
  1759. catch (MP4Error* e) {
  1760. PRINT_ERROR(e);
  1761. delete e;
  1762. }
  1763. }
  1764. return false;
  1765. }
  1766. extern "C" MP4Timestamp MP4GetRtpTimestampStart(
  1767. MP4FileHandle hFile,
  1768. MP4TrackId hintTrackId)
  1769. {
  1770. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1771. try {
  1772. return ((MP4File*)hFile)->GetRtpTimestampStart(hintTrackId);
  1773. }
  1774. catch (MP4Error* e) {
  1775. PRINT_ERROR(e);
  1776. delete e;
  1777. }
  1778. }
  1779. return MP4_INVALID_TIMESTAMP;
  1780. }
  1781. extern "C" bool MP4SetRtpTimestampStart(
  1782. MP4FileHandle hFile,
  1783. MP4TrackId hintTrackId,
  1784. MP4Timestamp rtpStart)
  1785. {
  1786. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1787. try {
  1788. ((MP4File*)hFile)->SetRtpTimestampStart(
  1789. hintTrackId, rtpStart);
  1790. return true;
  1791. }
  1792. catch (MP4Error* e) {
  1793. PRINT_ERROR(e);
  1794. delete e;
  1795. }
  1796. }
  1797. return false;
  1798. }
  1799. extern "C" bool MP4AddRtpHint(
  1800. MP4FileHandle hFile,
  1801. MP4TrackId hintTrackId)
  1802. {
  1803. return MP4AddRtpVideoHint(hFile, hintTrackId, false, 0);
  1804. }
  1805. extern "C" bool MP4AddRtpVideoHint(
  1806. MP4FileHandle hFile,
  1807. MP4TrackId hintTrackId,
  1808. bool isBframe, 
  1809. u_int32_t timestampOffset)
  1810. {
  1811. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1812. try {
  1813. ((MP4File*)hFile)->AddRtpHint(hintTrackId, 
  1814. isBframe, timestampOffset);
  1815. return true;
  1816. }
  1817. catch (MP4Error* e) {
  1818. PRINT_ERROR(e);
  1819. delete e;
  1820. }
  1821. }
  1822. return false;
  1823. }
  1824. extern "C" bool MP4AddRtpPacket(
  1825. MP4FileHandle hFile,
  1826. MP4TrackId hintTrackId,
  1827. bool setMbit,
  1828. int32_t transmitOffset)
  1829. {
  1830. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1831. try {
  1832. ((MP4File*)hFile)->AddRtpPacket(
  1833. hintTrackId, setMbit, transmitOffset);
  1834. return true;
  1835. }
  1836. catch (MP4Error* e) {
  1837. PRINT_ERROR(e);
  1838. delete e;
  1839. }
  1840. }
  1841. return false;
  1842. }
  1843. extern "C" bool MP4AddRtpImmediateData(
  1844. MP4FileHandle hFile,
  1845. MP4TrackId hintTrackId,
  1846. const u_int8_t* pBytes,
  1847. u_int32_t numBytes)
  1848. {
  1849. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1850. try {
  1851. ((MP4File*)hFile)->AddRtpImmediateData(hintTrackId, 
  1852. pBytes, numBytes);
  1853. return true;
  1854. }
  1855. catch (MP4Error* e) {
  1856. PRINT_ERROR(e);
  1857. delete e;
  1858. }
  1859. }
  1860. return false;
  1861. }
  1862. extern "C" bool MP4AddRtpSampleData(
  1863. MP4FileHandle hFile,
  1864. MP4TrackId hintTrackId,
  1865. MP4SampleId sampleId,
  1866. u_int32_t dataOffset,
  1867. u_int32_t dataLength)
  1868. {
  1869. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1870. try {
  1871. ((MP4File*)hFile)->AddRtpSampleData(
  1872. hintTrackId, sampleId, dataOffset, dataLength);
  1873. return true;
  1874. }
  1875. catch (MP4Error* e) {
  1876. PRINT_ERROR(e);
  1877. delete e;
  1878. }
  1879. }
  1880. return false;
  1881. }
  1882. extern "C" bool MP4AddRtpESConfigurationPacket(
  1883. MP4FileHandle hFile,
  1884. MP4TrackId hintTrackId)
  1885. {
  1886. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1887. try {
  1888. ((MP4File*)hFile)->AddRtpESConfigurationPacket(hintTrackId);
  1889. return true;
  1890. }
  1891. catch (MP4Error* e) {
  1892. PRINT_ERROR(e);
  1893. delete e;
  1894. }
  1895. }
  1896. return false;
  1897. }
  1898. extern "C" bool MP4WriteRtpHint(
  1899. MP4FileHandle hFile,
  1900. MP4TrackId hintTrackId,
  1901. MP4Duration duration,
  1902. bool isSyncSample)
  1903. {
  1904. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1905. try {
  1906. ((MP4File*)hFile)->WriteRtpHint(
  1907. hintTrackId, duration, isSyncSample);
  1908. return true;
  1909. }
  1910. catch (MP4Error* e) {
  1911. PRINT_ERROR(e);
  1912. delete e;
  1913. }
  1914. }
  1915. return false;
  1916. }
  1917. /* ISMA specific operations */
  1918. extern "C" bool MP4MakeIsmaCompliant(
  1919. const char* fileName, 
  1920. u_int32_t verbosity,
  1921. bool addIsmaComplianceSdp)
  1922. {
  1923. MP4File* pFile = NULL;
  1924. try {
  1925. pFile = new MP4File(verbosity);
  1926. pFile->Modify(fileName);
  1927. pFile->MakeIsmaCompliant(addIsmaComplianceSdp);
  1928. pFile->Close();
  1929. delete pFile;
  1930. return true;
  1931. }
  1932. catch (MP4Error* e) {
  1933. VERBOSE_ERROR(verbosity, e->Print());
  1934. delete e;
  1935. }
  1936. delete pFile;
  1937. return false;
  1938. }
  1939. extern "C" char* MP4MakeIsmaSdpIod(
  1940. u_int8_t videoProfile,
  1941. u_int32_t videoBitrate,
  1942. u_int8_t* videoConfig,
  1943. u_int32_t videoConfigLength,
  1944. u_int8_t audioProfile,
  1945. u_int32_t audioBitrate,
  1946. u_int8_t* audioConfig,
  1947. u_int32_t audioConfigLength,
  1948. u_int32_t verbosity)
  1949. {
  1950. MP4File* pFile = NULL;
  1951. try {
  1952. pFile = new MP4File(verbosity);
  1953. u_int8_t* pBytes = NULL;
  1954. u_int64_t numBytes = 0;
  1955. pFile->CreateIsmaIodFromParams(
  1956. videoProfile,
  1957. videoBitrate,
  1958. videoConfig,
  1959. videoConfigLength,
  1960. audioProfile,
  1961. audioBitrate,
  1962. audioConfig,
  1963. audioConfigLength,
  1964. &pBytes,
  1965. &numBytes);
  1966. char* iodBase64 = 
  1967. MP4ToBase64(pBytes, numBytes);
  1968. MP4Free(pBytes);
  1969. char* sdpIod = 
  1970. (char*)MP4Malloc(strlen(iodBase64) + 64);
  1971. sprintf(sdpIod,
  1972. "a=mpeg4-iod: 42data:application/mpeg4-iod;base64,%s42",
  1973. iodBase64);
  1974. MP4Free(iodBase64);
  1975. delete pFile;
  1976. return sdpIod;
  1977. }
  1978. catch (MP4Error* e) {
  1979. VERBOSE_ERROR(verbosity, e->Print());
  1980. delete e;
  1981. }
  1982. delete pFile;
  1983. return NULL;
  1984. }
  1985. /* Edit list */
  1986. extern "C" MP4EditId MP4AddTrackEdit(
  1987. MP4FileHandle hFile,
  1988. MP4TrackId trackId,
  1989. MP4EditId editId,
  1990. MP4Timestamp startTime,
  1991. MP4Duration duration,
  1992. bool dwell)
  1993. {
  1994. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  1995. try {
  1996. MP4EditId editId =
  1997. ((MP4File*)hFile)->AddTrackEdit(trackId, editId);
  1998. if (editId != MP4_INVALID_EDIT_ID) {
  1999. ((MP4File*)hFile)->SetTrackEditMediaStart(
  2000. trackId, editId, startTime);
  2001. ((MP4File*)hFile)->SetTrackEditDuration(
  2002. trackId, editId, duration);
  2003. ((MP4File*)hFile)->SetTrackEditDwell(
  2004. trackId, editId, dwell);
  2005. }
  2006. return editId;
  2007. }
  2008. catch (MP4Error* e) {
  2009. PRINT_ERROR(e);
  2010. delete e;
  2011. }
  2012. }
  2013. return MP4_INVALID_EDIT_ID;
  2014. }
  2015. extern "C" bool MP4DeleteTrackEdit(
  2016. MP4FileHandle hFile,
  2017. MP4TrackId trackId,
  2018. MP4EditId editId)
  2019. {
  2020. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2021. try {
  2022. ((MP4File*)hFile)->DeleteTrackEdit(trackId, editId);
  2023. return true;
  2024. }
  2025. catch (MP4Error* e) {
  2026. PRINT_ERROR(e);
  2027. delete e;
  2028. }
  2029. }
  2030. return false;
  2031. }
  2032. extern "C" u_int32_t MP4GetTrackNumberOfEdits(
  2033. MP4FileHandle hFile,
  2034. MP4TrackId trackId)
  2035. {
  2036. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2037. try {
  2038. return ((MP4File*)hFile)->GetTrackNumberOfEdits(trackId);
  2039. }
  2040. catch (MP4Error* e) {
  2041. PRINT_ERROR(e);
  2042. delete e;
  2043. }
  2044. }
  2045. return 0;
  2046. }
  2047. extern "C" MP4Timestamp MP4GetTrackEditMediaStart(
  2048. MP4FileHandle hFile,
  2049. MP4TrackId trackId,
  2050. MP4EditId editId)
  2051. {
  2052. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2053. try {
  2054. return ((MP4File*)hFile)->GetTrackEditMediaStart(
  2055. trackId, editId);
  2056. }
  2057. catch (MP4Error* e) {
  2058. PRINT_ERROR(e);
  2059. delete e;
  2060. }
  2061. }
  2062. return MP4_INVALID_TIMESTAMP;
  2063. }
  2064. extern "C" MP4Duration MP4GetTrackEditTotalDuration(
  2065. MP4FileHandle hFile,
  2066. MP4TrackId trackId,
  2067. MP4EditId editId)
  2068. {
  2069. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2070. try {
  2071. return ((MP4File*)hFile)->GetTrackEditTotalDuration(
  2072. trackId, editId);
  2073. }
  2074. catch (MP4Error* e) {
  2075. PRINT_ERROR(e);
  2076. delete e;
  2077. }
  2078. }
  2079. return MP4_INVALID_DURATION;
  2080. }
  2081. extern "C" bool MP4SetTrackEditMediaStart(
  2082. MP4FileHandle hFile,
  2083. MP4TrackId trackId,
  2084. MP4EditId editId,
  2085. MP4Timestamp startTime)
  2086. {
  2087. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2088. try {
  2089. ((MP4File*)hFile)->SetTrackEditMediaStart(
  2090. trackId, editId, startTime);
  2091. return true;
  2092. }
  2093. catch (MP4Error* e) {
  2094. PRINT_ERROR(e);
  2095. delete e;
  2096. }
  2097. }
  2098. return false;
  2099. }
  2100. extern "C" MP4Duration MP4GetTrackEditDuration(
  2101. MP4FileHandle hFile,
  2102. MP4TrackId trackId,
  2103. MP4EditId editId)
  2104. {
  2105. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2106. try {
  2107. return ((MP4File*)hFile)->GetTrackEditDuration(trackId, editId);
  2108. }
  2109. catch (MP4Error* e) {
  2110. PRINT_ERROR(e);
  2111. delete e;
  2112. }
  2113. }
  2114. return MP4_INVALID_DURATION;
  2115. }
  2116. extern "C" bool MP4SetTrackEditDuration(
  2117. MP4FileHandle hFile,
  2118. MP4TrackId trackId,
  2119. MP4EditId editId,
  2120. MP4Duration duration)
  2121. {
  2122. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2123. try {
  2124. ((MP4File*)hFile)->SetTrackEditDuration(trackId, editId, duration);
  2125. return true;
  2126. }
  2127. catch (MP4Error* e) {
  2128. PRINT_ERROR(e);
  2129. delete e;
  2130. }
  2131. }
  2132. return false;
  2133. }
  2134. extern "C" int8_t MP4GetTrackEditDwell(
  2135. MP4FileHandle hFile,
  2136. MP4TrackId trackId,
  2137. MP4EditId editId)
  2138. {
  2139. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2140. try {
  2141. return ((MP4File*)hFile)->GetTrackEditDwell(trackId, editId);
  2142. }
  2143. catch (MP4Error* e) {
  2144. PRINT_ERROR(e);
  2145. delete e;
  2146. }
  2147. }
  2148. return -1;
  2149. }
  2150. extern "C" bool MP4SetTrackEditDwell(
  2151. MP4FileHandle hFile,
  2152. MP4TrackId trackId,
  2153. MP4EditId editId,
  2154. bool dwell)
  2155. {
  2156. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2157. try {
  2158. ((MP4File*)hFile)->SetTrackEditDwell(trackId, editId, dwell);
  2159. return true;
  2160. }
  2161. catch (MP4Error* e) {
  2162. PRINT_ERROR(e);
  2163. delete e;
  2164. }
  2165. }
  2166. return false;
  2167. }
  2168. extern "C" bool MP4ReadSampleFromEditTime(
  2169. /* input parameters */
  2170. MP4FileHandle hFile,
  2171. MP4TrackId trackId, 
  2172. MP4Timestamp when,
  2173. /* output parameters */
  2174. u_int8_t** ppBytes, 
  2175. u_int32_t* pNumBytes, 
  2176. MP4Timestamp* pStartTime, 
  2177. MP4Duration* pDuration,
  2178. MP4Duration* pRenderingOffset, 
  2179. bool* pIsSyncSample)
  2180. {
  2181. MP4SampleId sampleId = 
  2182. MP4GetSampleIdFromEditTime(
  2183. hFile,
  2184. trackId, 
  2185. when, 
  2186. pStartTime,
  2187. pDuration);
  2188. return MP4ReadSample(
  2189. hFile,
  2190. trackId, 
  2191. sampleId, 
  2192. ppBytes, 
  2193. pNumBytes, 
  2194. NULL,
  2195. NULL, 
  2196. pRenderingOffset, 
  2197. pIsSyncSample);
  2198. }
  2199. extern "C" MP4SampleId MP4GetSampleIdFromEditTime(
  2200. MP4FileHandle hFile,
  2201. MP4TrackId trackId, 
  2202. MP4Timestamp when,
  2203. MP4Timestamp* pStartTime,
  2204. MP4Duration* pDuration)
  2205. {
  2206. if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
  2207. try {
  2208. return ((MP4File*)hFile)->GetSampleIdFromEditTime(
  2209. trackId, when, pStartTime, pDuration);
  2210. }
  2211. catch (MP4Error* e) {
  2212. PRINT_ERROR(e);
  2213. delete e;
  2214. }
  2215. }
  2216. return MP4_INVALID_SAMPLE_ID;
  2217. }
  2218. /* Utlities */
  2219. extern "C" char* MP4BinaryToBase16(
  2220. const u_int8_t* pData, 
  2221. u_int32_t dataSize)
  2222. {
  2223. if (pData || dataSize == 0) {
  2224. try {
  2225. return MP4ToBase16(pData, dataSize);
  2226. }
  2227. catch (MP4Error* e) {
  2228. delete e;
  2229. }
  2230. }
  2231. return NULL;
  2232. }
  2233. extern "C" char* MP4BinaryToBase64(
  2234. const u_int8_t* pData, 
  2235. u_int32_t dataSize)
  2236. {
  2237. if (pData || dataSize == 0) {
  2238. try {
  2239. return MP4ToBase64(pData, dataSize);
  2240. }
  2241. catch (MP4Error* e) {
  2242. delete e;
  2243. }
  2244. }
  2245. return NULL;
  2246. }