ref: 5a1ffaa6a50fd05e7a4a8079941d1b7eb2ef3db9
dir: /common/mp4v2/mp4.cpp/
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is MPEG4IP.
*
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
*
* Contributor(s):
* Dave Mackie dmackie@cisco.com
* Alix Marchandise-Franquet alix@cisco.com
*/
/*
* MP4 library API functions
*
* These are wrapper functions that provide C linkage conventions
* to the library, and catch any internal errors, ensuring that
* a proper return value is given.
*/
#include "mp4common.h"
#define PRINT_ERROR(e) \
VERBOSE_ERROR(((MP4File*)hFile)->GetVerbosity(), e->Print());
/* file operations */
extern "C" MP4FileHandle MP4Read(const char* fileName, u_int32_t verbosity)
{
MP4File* pFile = NULL;
try {
pFile = new MP4File(verbosity);
pFile->Read(fileName);
return (MP4FileHandle)pFile;
}
catch (MP4Error* e) {
VERBOSE_ERROR(verbosity, e->Print());
delete e;
delete pFile;
return MP4_INVALID_FILE_HANDLE;
}
}
#ifdef USE_FILE_CALLBACKS
extern "C" MP4FileHandle MP4CreateCb(u_int32_t verbosity,
bool use64bits,
bool useExtensibleFormat,
MP4OpenCallback MP4fopen,
MP4CloseCallback MP4fclose,
MP4ReadCallback MP4fread,
MP4WriteCallback MP4fwrite,
MP4SetposCallback MP4fsetpos,
MP4GetposCallback MP4fgetpos,
MP4FilesizeCallback MP4filesize,
void *userData)
{
MP4File* pFile = NULL;
try {
pFile = new MP4File(verbosity);
// LATER useExtensibleFormat, moov first, then mvex's
// Set user data and callbacks
pFile->m_userData = userData;
pFile->m_MP4fopen = MP4fopen;
pFile->m_MP4fclose = MP4fclose;
pFile->m_MP4fread = MP4fread;
pFile->m_MP4fwrite = MP4fwrite;
pFile->m_MP4fsetpos = MP4fsetpos;
pFile->m_MP4fgetpos = MP4fgetpos;
pFile->m_MP4filesize = MP4filesize;
pFile->Create("", use64bits);
return (MP4FileHandle)pFile;
}
catch (MP4Error* e) {
VERBOSE_ERROR(verbosity, e->Print());
delete e;
delete pFile;
return MP4_INVALID_FILE_HANDLE;
}
}
extern "C" MP4FileHandle MP4ReadCb(u_int32_t verbosity,
MP4OpenCallback MP4fopen,
MP4CloseCallback MP4fclose,
MP4ReadCallback MP4fread,
MP4WriteCallback MP4fwrite,
MP4SetposCallback MP4fsetpos,
MP4GetposCallback MP4fgetpos,
MP4FilesizeCallback MP4filesize,
void *userData
)
{
MP4File* pFile = NULL;
try {
pFile = new MP4File(verbosity);
// Set user data and callbacks
pFile->m_userData = userData;
pFile->m_MP4fopen = MP4fopen;
pFile->m_MP4fclose = MP4fclose;
pFile->m_MP4fread = MP4fread;
pFile->m_MP4fwrite = MP4fwrite;
pFile->m_MP4fsetpos = MP4fsetpos;
pFile->m_MP4fgetpos = MP4fgetpos;
pFile->m_MP4filesize = MP4filesize;
pFile->Read("");
return (MP4FileHandle)pFile;
}
catch (MP4Error* e) {
VERBOSE_ERROR(verbosity, e->Print());
delete e;
delete pFile;
return MP4_INVALID_FILE_HANDLE;
}
}
extern "C" MP4FileHandle MP4ModifyCb(int32_t verbosity,
bool useExtensibleFormat,
MP4OpenCallback MP4fopen, MP4CloseCallback MP4fclose,
MP4ReadCallback MP4fread, MP4WriteCallback MP4fwrite,
MP4SetposCallback MP4fsetpos, MP4GetposCallback MP4fgetpos,
MP4FilesizeCallback MP4filesize, void *userData)
{
MP4File* pFile = NULL;
try {
pFile = new MP4File(verbosity);
// Set user data and callbacks
pFile->m_userData = userData;
pFile->m_MP4fopen = MP4fopen;
pFile->m_MP4fclose = MP4fclose;
pFile->m_MP4fread = MP4fread;
pFile->m_MP4fwrite = MP4fwrite;
pFile->m_MP4fsetpos = MP4fsetpos;
pFile->m_MP4fgetpos = MP4fgetpos;
pFile->m_MP4filesize = MP4filesize;
// LATER useExtensibleFormat, moov first, then mvex's
pFile->Modify("");
return (MP4FileHandle)pFile;
}
catch (MP4Error* e) {
VERBOSE_ERROR(verbosity, e->Print());
delete e;
delete pFile;
return MP4_INVALID_FILE_HANDLE;
}
}
#endif
extern "C" MP4FileHandle MP4Create(const char* fileName,
u_int32_t verbosity, bool use64bits, bool useExtensibleFormat)
{
MP4File* pFile = NULL;
try {
pFile = new MP4File(verbosity);
// LATER useExtensibleFormat, moov first, then mvex's
pFile->Create(fileName, use64bits);
return (MP4FileHandle)pFile;
}
catch (MP4Error* e) {
VERBOSE_ERROR(verbosity, e->Print());
delete e;
delete pFile;
return MP4_INVALID_FILE_HANDLE;
}
}
extern "C" MP4FileHandle MP4Modify(const char* fileName,
u_int32_t verbosity, bool useExtensibleFormat)
{
MP4File* pFile = NULL;
try {
pFile = new MP4File(verbosity);
// LATER useExtensibleFormat, moov first, then mvex's
pFile->Modify(fileName);
return (MP4FileHandle)pFile;
}
catch (MP4Error* e) {
VERBOSE_ERROR(verbosity, e->Print());
delete e;
delete pFile;
return MP4_INVALID_FILE_HANDLE;
}
}
extern "C" bool MP4Optimize(const char* existingFileName,
const char* newFileName,
u_int32_t verbosity)
{
try {
MP4File* pFile = new MP4File(verbosity);
pFile->Optimize(existingFileName, newFileName);
delete pFile;
return true;
}
catch (MP4Error* e) {
VERBOSE_ERROR(verbosity, e->Print());
delete e;
}
return false;
}
extern "C" bool MP4Close(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->Close();
delete (MP4File*)hFile;
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4Dump(
MP4FileHandle hFile,
FILE* pDumpFile,
bool dumpImplicits)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->Dump(pDumpFile, dumpImplicits);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
/* specific file properties */
extern "C" u_int32_t MP4GetVerbosity(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetVerbosity();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool MP4SetVerbosity(MP4FileHandle hFile, u_int32_t verbosity)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetVerbosity(verbosity);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" MP4Duration MP4GetDuration(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetDuration();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_DURATION;
}
extern "C" u_int32_t MP4GetTimeScale(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTimeScale();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool MP4SetTimeScale(MP4FileHandle hFile, u_int32_t value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTimeScale(value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" u_int8_t MP4GetODProfileLevel(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetODProfileLevel();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool MP4SetODProfileLevel(MP4FileHandle hFile, u_int8_t value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetODProfileLevel(value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" u_int8_t MP4GetSceneProfileLevel(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetSceneProfileLevel();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool MP4SetSceneProfileLevel(MP4FileHandle hFile, u_int8_t value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetSceneProfileLevel(value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" u_int8_t MP4GetVideoProfileLevel(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetVideoProfileLevel();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool MP4SetVideoProfileLevel(MP4FileHandle hFile, u_int8_t value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetVideoProfileLevel(value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" u_int8_t MP4GetAudioProfileLevel(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetAudioProfileLevel();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool MP4SetAudioProfileLevel(MP4FileHandle hFile, u_int8_t value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetAudioProfileLevel(value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" u_int8_t MP4GetGraphicsProfileLevel(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetGraphicsProfileLevel();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool MP4SetGraphicsProfileLevel(MP4FileHandle hFile, u_int8_t value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetGraphicsProfileLevel(value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
/* generic file properties */
extern "C" u_int64_t MP4GetIntegerProperty(
MP4FileHandle hFile, const char* propName)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetIntegerProperty(propName);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return (u_int64_t)-1;
}
extern "C" float MP4GetFloatProperty(
MP4FileHandle hFile, const char* propName)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetFloatProperty(propName);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return NAN;
}
extern "C" const char* MP4GetStringProperty(
MP4FileHandle hFile, const char* propName)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetStringProperty(propName);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return NULL;
}
extern "C" void MP4GetBytesProperty(
MP4FileHandle hFile, const char* propName,
u_int8_t** ppValue, u_int32_t* pValueSize)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->GetBytesProperty(propName, ppValue, pValueSize);
return;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
*ppValue = NULL;
*pValueSize = 0;
return;
}
extern "C" bool MP4SetIntegerProperty(
MP4FileHandle hFile, const char* propName, int64_t value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetIntegerProperty(propName, value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetFloatProperty(
MP4FileHandle hFile, const char* propName, float value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetFloatProperty(propName, value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetStringProperty(
MP4FileHandle hFile, const char* propName, const char* value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetStringProperty(propName, value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetBytesProperty(
MP4FileHandle hFile, const char* propName,
const u_int8_t* pValue, u_int32_t valueSize)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetBytesProperty(propName, pValue, valueSize);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
/* track operations */
extern "C" MP4TrackId MP4AddTrack(
MP4FileHandle hFile, const char* type)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->AddSystemsTrack(type);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" MP4TrackId MP4AddSystemsTrack(
MP4FileHandle hFile, const char* type)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->AddSystemsTrack(type);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" MP4TrackId MP4AddODTrack(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->AddODTrack();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" MP4TrackId MP4AddSceneTrack(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->AddSceneTrack();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" MP4TrackId MP4AddAudioTrack(
MP4FileHandle hFile,
u_int32_t timeScale,
MP4Duration sampleDuration,
u_int8_t audioType)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->
AddAudioTrack(timeScale, sampleDuration, audioType);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" MP4TrackId MP4AddEncAudioTrack(MP4FileHandle hFile,
u_int32_t timeScale,
MP4Duration sampleDuration,
u_int8_t audioType)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->
AddEncAudioTrack(timeScale, sampleDuration, audioType);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" MP4TrackId MP4AddVideoTrack(
MP4FileHandle hFile,
u_int32_t timeScale,
MP4Duration sampleDuration,
u_int16_t width,
u_int16_t height,
u_int8_t videoType)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->AddVideoTrack(
timeScale, sampleDuration, width, height, videoType);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" MP4TrackId MP4AddEncVideoTrack(MP4FileHandle hFile,
u_int32_t timeScale,
MP4Duration sampleDuration,
u_int16_t width,
u_int16_t height,
u_int8_t videoType)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->AddEncVideoTrack(timeScale, sampleDuration,
width, height, videoType);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" MP4TrackId MP4AddHintTrack(
MP4FileHandle hFile, MP4TrackId refTrackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->AddHintTrack(refTrackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" MP4TrackId MP4CloneTrack(
MP4FileHandle srcFile,
MP4TrackId srcTrackId,
MP4FileHandle dstFile)
{
MP4TrackId dstTrackId = MP4_INVALID_TRACK_ID;
if (dstFile == NULL) {
dstFile = srcFile;
}
const char* trackType =
MP4GetTrackType(srcFile, srcTrackId);
if (!trackType) {
return dstTrackId;
}
if (MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
MP4SetVideoProfileLevel(dstFile,
MP4GetVideoProfileLevel(srcFile));
dstTrackId = MP4AddVideoTrack(
dstFile,
MP4GetTrackTimeScale(srcFile, srcTrackId),
MP4GetTrackFixedSampleDuration(srcFile, srcTrackId),
MP4GetTrackVideoWidth(srcFile, srcTrackId),
MP4GetTrackVideoHeight(srcFile, srcTrackId),
MP4GetTrackEsdsObjectTypeId(srcFile, srcTrackId));
} else if (MP4_IS_AUDIO_TRACK_TYPE(trackType)) {
MP4SetAudioProfileLevel(dstFile,
MP4GetAudioProfileLevel(srcFile));
dstTrackId = MP4AddAudioTrack(
dstFile,
MP4GetTrackTimeScale(srcFile, srcTrackId),
MP4GetTrackFixedSampleDuration(srcFile, srcTrackId),
MP4GetTrackEsdsObjectTypeId(srcFile, srcTrackId));
} else if (MP4_IS_OD_TRACK_TYPE(trackType)) {
dstTrackId = MP4AddODTrack(dstFile);
} else if (MP4_IS_SCENE_TRACK_TYPE(trackType)) {
dstTrackId = MP4AddSceneTrack(dstFile);
} else if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
dstTrackId = MP4AddHintTrack(
dstFile,
MP4GetHintTrackReferenceTrackId(srcFile, srcTrackId));
} else if (MP4_IS_SYSTEMS_TRACK_TYPE(trackType)) {
dstTrackId = MP4AddSystemsTrack(dstFile, trackType);
} else {
dstTrackId = MP4AddTrack(dstFile, trackType);
}
if (dstTrackId == MP4_INVALID_TRACK_ID) {
return dstTrackId;
}
MP4SetTrackTimeScale(
dstFile,
dstTrackId,
MP4GetTrackTimeScale(srcFile, srcTrackId));
if (MP4_IS_AUDIO_TRACK_TYPE(trackType)
|| MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
// copy track ES configuration
u_int8_t* pConfig = NULL;
u_int32_t configSize = 0;
MP4GetTrackESConfiguration(
srcFile,
srcTrackId,
&pConfig,
&configSize);
MP4SetTrackESConfiguration(
dstFile,
dstTrackId,
pConfig,
configSize);
free(pConfig);
}
if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
// probably not exactly what is wanted
// but caller can adjust later to fit their desires
char* payloadName = NULL;
char *encodingParms = NULL;
u_int8_t payloadNumber;
u_int16_t maxPayloadSize;
MP4GetHintTrackRtpPayload(
srcFile,
srcTrackId,
&payloadName,
&payloadNumber,
&maxPayloadSize,
&encodingParms);
MP4SetHintTrackRtpPayload(
dstFile,
dstTrackId,
payloadName,
&payloadNumber,
maxPayloadSize,
encodingParms);
MP4SetHintTrackSdp(
dstFile,
dstTrackId,
MP4GetHintTrackSdp(srcFile, srcTrackId));
}
return dstTrackId;
}
// Given a track, make an encrypted clone of it in the dest. file
extern "C" MP4TrackId MP4EncAndCloneTrack(MP4FileHandle srcFile,
MP4TrackId srcTrackId,
MP4FileHandle dstFile)
{
MP4TrackId dstTrackId = MP4_INVALID_TRACK_ID;
if (dstFile == NULL) {
dstFile = srcFile;
}
const char* trackType =
MP4GetTrackType(srcFile, srcTrackId);
if (!trackType) {
return dstTrackId;
}
if (MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
MP4SetVideoProfileLevel(dstFile, MP4GetVideoProfileLevel(srcFile));
dstTrackId = MP4AddEncVideoTrack(dstFile,
MP4GetTrackTimeScale(srcFile, srcTrackId),
MP4GetTrackFixedSampleDuration(srcFile,
srcTrackId),
MP4GetTrackVideoWidth(srcFile, srcTrackId),
MP4GetTrackVideoHeight(srcFile, srcTrackId),
MP4GetTrackEsdsObjectTypeId(srcFile,
srcTrackId));
} else if (MP4_IS_AUDIO_TRACK_TYPE(trackType)) {
MP4SetAudioProfileLevel(dstFile, MP4GetAudioProfileLevel(srcFile));
dstTrackId = MP4AddEncAudioTrack(dstFile,
MP4GetTrackTimeScale(srcFile, srcTrackId),
MP4GetTrackFixedSampleDuration(srcFile,
srcTrackId),
MP4GetTrackEsdsObjectTypeId(srcFile,
srcTrackId));
} else if (MP4_IS_OD_TRACK_TYPE(trackType)) {
dstTrackId = MP4AddODTrack(dstFile);
} else if (MP4_IS_SCENE_TRACK_TYPE(trackType)) {
dstTrackId = MP4AddSceneTrack(dstFile);
} else if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
dstTrackId = MP4AddHintTrack(dstFile,
MP4GetHintTrackReferenceTrackId(srcFile,
srcTrackId));
} else if (MP4_IS_SYSTEMS_TRACK_TYPE(trackType)) {
dstTrackId = MP4AddSystemsTrack(dstFile, trackType);
} else {
dstTrackId = MP4AddTrack(dstFile, trackType);
}
if (dstTrackId == MP4_INVALID_TRACK_ID) {
return dstTrackId;
}
MP4SetTrackTimeScale(dstFile,
dstTrackId,
MP4GetTrackTimeScale(srcFile, srcTrackId));
if (MP4_IS_AUDIO_TRACK_TYPE(trackType)
|| MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
// copy track ES configuration
u_int8_t* pConfig = NULL;
u_int32_t configSize = 0;
if (MP4GetTrackESConfiguration(srcFile, srcTrackId,
&pConfig, &configSize)) {
if (pConfig != NULL) {
MP4SetTrackESConfiguration(dstFile, dstTrackId,
pConfig, configSize);
}
}
if (pConfig != NULL)
free(pConfig);
}
return dstTrackId;
}
extern "C" MP4TrackId MP4CopyTrack(MP4FileHandle srcFile,
MP4TrackId srcTrackId,
MP4FileHandle dstFile,
bool applyEdits)
{
bool copySamples = true; // LATER allow false => reference samples
MP4TrackId dstTrackId =
MP4CloneTrack(srcFile, srcTrackId, dstFile);
if (dstTrackId == MP4_INVALID_TRACK_ID) {
return dstTrackId;
}
bool viaEdits =
applyEdits && MP4GetTrackNumberOfEdits(srcFile, srcTrackId);
MP4SampleId sampleId = 0;
MP4SampleId numSamples =
MP4GetTrackNumberOfSamples(srcFile, srcTrackId);
MP4Timestamp when = 0;
MP4Duration editsDuration =
MP4GetTrackEditTotalDuration(srcFile, srcTrackId);
while (true) {
MP4Duration sampleDuration = MP4_INVALID_DURATION;
if (viaEdits) {
sampleId = MP4GetSampleIdFromEditTime(
srcFile,
srcTrackId,
when,
NULL,
&sampleDuration);
// in theory, this shouldn't happen
if (sampleId == MP4_INVALID_SAMPLE_ID) {
MP4DeleteTrack(dstFile, dstTrackId);
return MP4_INVALID_TRACK_ID;
}
when += sampleDuration;
if (when >= editsDuration) {
break;
}
} else {
sampleId++;
if (sampleId > numSamples) {
break;
}
}
bool rc = false;
if (copySamples) {
rc = MP4CopySample(
srcFile,
srcTrackId,
sampleId,
dstFile,
dstTrackId,
sampleDuration);
} else {
rc = MP4ReferenceSample(
srcFile,
srcTrackId,
sampleId,
dstFile,
dstTrackId,
sampleDuration);
}
if (!rc) {
MP4DeleteTrack(dstFile, dstTrackId);
return MP4_INVALID_TRACK_ID;
}
}
return dstTrackId;
}
// Given a source track in a source file, make an encrypted copy of
// the track in the destination file, including sample encryption
extern "C" MP4TrackId MP4EncAndCopyTrack(MP4FileHandle srcFile,
MP4TrackId srcTrackId,
MP4FileHandle dstFile,
bool applyEdits)
{
bool copySamples = true; // LATER allow false => reference samples
MP4TrackId dstTrackId =
MP4EncAndCloneTrack(srcFile, srcTrackId, dstFile);
if (dstTrackId == MP4_INVALID_TRACK_ID) {
return dstTrackId;
}
bool viaEdits =
applyEdits && MP4GetTrackNumberOfEdits(srcFile, srcTrackId);
MP4SampleId sampleId = 0;
MP4SampleId numSamples =
MP4GetTrackNumberOfSamples(srcFile, srcTrackId);
MP4Timestamp when = 0;
MP4Duration editsDuration =
MP4GetTrackEditTotalDuration(srcFile, srcTrackId);
while (true) {
MP4Duration sampleDuration = MP4_INVALID_DURATION;
if (viaEdits) {
sampleId = MP4GetSampleIdFromEditTime(srcFile,
srcTrackId,
when,
NULL,
&sampleDuration);
// in theory, this shouldn't happen
if (sampleId == MP4_INVALID_SAMPLE_ID) {
MP4DeleteTrack(dstFile, dstTrackId);
return MP4_INVALID_TRACK_ID;
}
when += sampleDuration;
if (when >= editsDuration) {
break;
}
} else {
sampleId++;
if (sampleId > numSamples) {
break;
}
}
bool rc = false;
if (copySamples) {
// will need to encrypt the sample here
rc = MP4CopySample(srcFile,
srcTrackId,
sampleId,
dstFile,
dstTrackId,
sampleDuration);
} else {
rc = MP4ReferenceSample(srcFile,
srcTrackId,
sampleId,
dstFile,
dstTrackId,
sampleDuration);
}
if (!rc) {
MP4DeleteTrack(dstFile, dstTrackId);
return MP4_INVALID_TRACK_ID;
}
}
return dstTrackId;
}
extern "C" bool MP4DeleteTrack(
MP4FileHandle hFile,
MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->DeleteTrack(trackId);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" u_int32_t MP4GetNumberOfTracks(
MP4FileHandle hFile,
const char* type,
u_int8_t subType)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetNumberOfTracks(type, subType);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" MP4TrackId MP4FindTrackId(
MP4FileHandle hFile,
u_int16_t index,
const char* type,
u_int8_t subType)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->FindTrackId(index, type, subType);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" u_int16_t MP4FindTrackIndex(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->FindTrackIndex(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return (u_int16_t)-1;
}
/* specific track properties */
extern "C" const char* MP4GetTrackType(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackType(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return NULL;
}
extern "C" MP4Duration MP4GetTrackDuration(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackDuration(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_DURATION;
}
extern "C" u_int32_t MP4GetTrackTimeScale(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackTimeScale(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool MP4SetTrackTimeScale(
MP4FileHandle hFile, MP4TrackId trackId, u_int32_t value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTrackTimeScale(trackId, value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
// This function should not be used anymore
// use MP4GetTrackEsdsObjectTypeId instead
extern "C" u_int8_t MP4GetTrackAudioType(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackAudioType(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_AUDIO_TYPE;
}
extern "C" u_int8_t MP4GetTrackAudioMpeg4Type(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackAudioMpeg4Type(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_MPEG4_INVALID_AUDIO_TYPE;
}
// This function should not be used anymore
// use MP4GetTrackEsdsObjectTypeId instead
extern "C" u_int8_t MP4GetTrackVideoType(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackVideoType(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_VIDEO_TYPE;
}
// Replacement to MP4GetTrackVideoType and MP4GetTrackAudioType
// Basically does the same thing but with a more self-explanatory name
extern "C" u_int8_t MP4GetTrackEsdsObjectTypeId(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackEsdsObjectTypeId(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_AUDIO_TYPE;
}
extern "C" MP4Duration MP4GetTrackFixedSampleDuration(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackFixedSampleDuration(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_DURATION;
}
extern "C" u_int32_t MP4GetTrackBitRate(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.*.esds.decConfigDescr.avgBitrate");
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool MP4GetTrackESConfiguration(
MP4FileHandle hFile, MP4TrackId trackId,
u_int8_t** ppConfig, u_int32_t* pConfigSize)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->GetTrackESConfiguration(
trackId, ppConfig, pConfigSize);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
*ppConfig = NULL;
*pConfigSize = 0;
return false;
}
extern "C" bool MP4SetTrackESConfiguration(
MP4FileHandle hFile, MP4TrackId trackId,
const u_int8_t* pConfig, u_int32_t configSize)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTrackESConfiguration(
trackId, pConfig, configSize);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" MP4SampleId MP4GetTrackNumberOfSamples(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackNumberOfSamples(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" u_int16_t MP4GetTrackVideoWidth(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.*.width");
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" u_int16_t MP4GetTrackVideoHeight(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.*.height");
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" float MP4GetTrackVideoFrameRate(
MP4FileHandle hFile, MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackVideoFrameRate(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0.0;
}
/* generic track properties */
extern "C" u_int64_t MP4GetTrackIntegerProperty(
MP4FileHandle hFile, MP4TrackId trackId,
const char* propName)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
propName);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return (u_int64_t)-1;
}
extern "C" float MP4GetTrackFloatProperty(
MP4FileHandle hFile, MP4TrackId trackId,
const char* propName)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackFloatProperty(trackId, propName);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return NAN;
}
extern "C" const char* MP4GetTrackStringProperty(
MP4FileHandle hFile, MP4TrackId trackId,
const char* propName)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackStringProperty(trackId, propName);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return NULL;
}
extern "C" void MP4GetTrackBytesProperty(
MP4FileHandle hFile, MP4TrackId trackId, const char* propName,
u_int8_t** ppValue, u_int32_t* pValueSize)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->GetTrackBytesProperty(
trackId, propName, ppValue, pValueSize);
return;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
*ppValue = NULL;
*pValueSize = 0;
return;
}
extern "C" bool MP4SetTrackIntegerProperty(
MP4FileHandle hFile, MP4TrackId trackId,
const char* propName, int64_t value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTrackIntegerProperty(trackId,
propName, value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetTrackFloatProperty(
MP4FileHandle hFile, MP4TrackId trackId,
const char* propName, float value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTrackFloatProperty(trackId, propName, value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetTrackStringProperty(
MP4FileHandle hFile, MP4TrackId trackId,
const char* propName, const char* value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTrackStringProperty(trackId, propName, value);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetTrackBytesProperty(
MP4FileHandle hFile, MP4TrackId trackId,
const char* propName, const u_int8_t* pValue, u_int32_t valueSize)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTrackBytesProperty(
trackId, propName, pValue, valueSize);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
/* sample operations */
extern "C" bool MP4ReadSample(
/* input parameters */
MP4FileHandle hFile,
MP4TrackId trackId,
MP4SampleId sampleId,
/* output parameters */
u_int8_t** ppBytes,
u_int32_t* pNumBytes,
MP4Timestamp* pStartTime,
MP4Duration* pDuration,
MP4Duration* pRenderingOffset,
bool* pIsSyncSample)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->ReadSample(
trackId,
sampleId,
ppBytes,
pNumBytes,
pStartTime,
pDuration,
pRenderingOffset,
pIsSyncSample);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
*pNumBytes = 0;
return false;
}
extern "C" bool MP4ReadSampleFromTime(
/* input parameters */
MP4FileHandle hFile,
MP4TrackId trackId,
MP4Timestamp when,
/* output parameters */
u_int8_t** ppBytes,
u_int32_t* pNumBytes,
MP4Timestamp* pStartTime,
MP4Duration* pDuration,
MP4Duration* pRenderingOffset,
bool* pIsSyncSample)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
MP4SampleId sampleId =
((MP4File*)hFile)->GetSampleIdFromTime(
trackId, when, false);
((MP4File*)hFile)->ReadSample(
trackId,
sampleId,
ppBytes,
pNumBytes,
pStartTime,
pDuration,
pRenderingOffset,
pIsSyncSample);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
*pNumBytes = 0;
return false;
}
extern "C" bool MP4WriteSample(
MP4FileHandle hFile,
MP4TrackId trackId,
const u_int8_t* pBytes,
u_int32_t numBytes,
MP4Duration duration,
MP4Duration renderingOffset,
bool isSyncSample)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->WriteSample(
trackId,
pBytes,
numBytes,
duration,
renderingOffset,
isSyncSample);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4CopySample(
MP4FileHandle srcFile,
MP4TrackId srcTrackId,
MP4SampleId srcSampleId,
MP4FileHandle dstFile,
MP4TrackId dstTrackId,
MP4Duration dstSampleDuration)
{
bool rc;
u_int8_t* pBytes = NULL;
u_int32_t numBytes = 0;
MP4Duration sampleDuration;
MP4Duration renderingOffset;
bool isSyncSample;
// Note: we leave it up to the caller to ensure that the
// source and destination tracks are compatible.
// i.e. copying audio samples into a video track
// is unlikely to do anything useful
rc = MP4ReadSample(
srcFile,
srcTrackId,
srcSampleId,
&pBytes,
&numBytes,
NULL,
&sampleDuration,
&renderingOffset,
&isSyncSample);
if (!rc) {
return false;
}
if (dstFile == MP4_INVALID_FILE_HANDLE) {
dstFile = srcFile;
}
if (dstTrackId == MP4_INVALID_TRACK_ID) {
dstTrackId = srcTrackId;
}
if (dstSampleDuration != MP4_INVALID_DURATION) {
sampleDuration = dstSampleDuration;
}
rc = MP4WriteSample(
dstFile,
dstTrackId,
pBytes,
numBytes,
sampleDuration,
renderingOffset,
isSyncSample);
free(pBytes);
return rc;
}
extern "C" bool MP4ReferenceSample(
MP4FileHandle srcFile,
MP4TrackId srcTrackId,
MP4SampleId srcSampleId,
MP4FileHandle dstFile,
MP4TrackId dstTrackId,
MP4Duration dstSampleDuration)
{
// LATER Not yet implemented
return false;
}
extern "C" u_int32_t MP4GetSampleSize(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4SampleId sampleId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetSampleSize(
trackId, sampleId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" u_int32_t MP4GetTrackMaxSampleSize(
MP4FileHandle hFile,
MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackMaxSampleSize(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" MP4SampleId MP4GetSampleIdFromTime(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4Timestamp when,
bool wantSyncSample)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetSampleIdFromTime(
trackId, when, wantSyncSample);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_SAMPLE_ID;
}
extern "C" MP4Timestamp MP4GetSampleTime(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4SampleId sampleId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetSampleTime(
trackId, sampleId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TIMESTAMP;
}
extern "C" MP4Duration MP4GetSampleDuration(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4SampleId sampleId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetSampleDuration(
trackId, sampleId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_DURATION;
}
extern "C" MP4Duration MP4GetSampleRenderingOffset(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4SampleId sampleId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetSampleRenderingOffset(
trackId, sampleId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_DURATION;
}
extern "C" bool MP4SetSampleRenderingOffset(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4SampleId sampleId,
MP4Duration renderingOffset)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetSampleRenderingOffset(
trackId, sampleId, renderingOffset);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" int8_t MP4GetSampleSync(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4SampleId sampleId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetSampleSync(
trackId, sampleId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return -1;
}
extern "C" u_int64_t MP4ConvertFromMovieDuration(
MP4FileHandle hFile,
MP4Duration duration,
u_int32_t timeScale)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->ConvertFromMovieDuration(
duration, timeScale);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return (u_int64_t)MP4_INVALID_DURATION;
}
extern "C" u_int64_t MP4ConvertFromTrackTimestamp(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4Timestamp timeStamp,
u_int32_t timeScale)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->ConvertFromTrackTimestamp(
trackId, timeStamp, timeScale);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return (u_int64_t)MP4_INVALID_TIMESTAMP;
}
extern "C" MP4Timestamp MP4ConvertToTrackTimestamp(
MP4FileHandle hFile,
MP4TrackId trackId,
u_int64_t timeStamp,
u_int32_t timeScale)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->ConvertToTrackTimestamp(
trackId, timeStamp, timeScale);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TIMESTAMP;
}
extern "C" u_int64_t MP4ConvertFromTrackDuration(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4Duration duration,
u_int32_t timeScale)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->ConvertFromTrackDuration(
trackId, duration, timeScale);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return (u_int64_t)MP4_INVALID_DURATION;
}
extern "C" MP4Duration MP4ConvertToTrackDuration(
MP4FileHandle hFile,
MP4TrackId trackId,
u_int64_t duration,
u_int32_t timeScale)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->ConvertToTrackDuration(
trackId, duration, timeScale);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_DURATION;
}
extern "C" bool MP4GetHintTrackRtpPayload(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
char** ppPayloadName,
u_int8_t* pPayloadNumber,
u_int16_t* pMaxPayloadSize,
char **ppEncodingParams)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->GetHintTrackRtpPayload(
hintTrackId, ppPayloadName, pPayloadNumber, pMaxPayloadSize,
ppEncodingParams);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool 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)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetHintTrackRtpPayload(
hintTrackId, pPayloadName, pPayloadNumber, maxPayloadSize, encode_params,
include_rtp_map, include_mpeg4_esid);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" const char* MP4GetSessionSdp(
MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetSessionSdp();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return NULL;
}
extern "C" bool MP4SetSessionSdp(
MP4FileHandle hFile,
const char* sdpString)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetSessionSdp(sdpString);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4AppendSessionSdp(
MP4FileHandle hFile,
const char* sdpString)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->AppendSessionSdp(sdpString);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" const char* MP4GetHintTrackSdp(
MP4FileHandle hFile,
MP4TrackId hintTrackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetHintTrackSdp(hintTrackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return NULL;
}
extern "C" bool MP4SetHintTrackSdp(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
const char* sdpString)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetHintTrackSdp(hintTrackId, sdpString);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4AppendHintTrackSdp(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
const char* sdpString)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->AppendHintTrackSdp(hintTrackId, sdpString);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" MP4TrackId MP4GetHintTrackReferenceTrackId(
MP4FileHandle hFile,
MP4TrackId hintTrackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->
GetHintTrackReferenceTrackId(hintTrackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TRACK_ID;
}
extern "C" bool MP4ReadRtpHint(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
MP4SampleId hintSampleId,
u_int16_t* pNumPackets)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->ReadRtpHint(
hintTrackId, hintSampleId, pNumPackets);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" u_int16_t MP4GetRtpHintNumberOfPackets(
MP4FileHandle hFile,
MP4TrackId hintTrackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetRtpHintNumberOfPackets(hintTrackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" int8_t MP4GetRtpPacketBFrame(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
u_int16_t packetIndex)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->
GetRtpPacketBFrame(hintTrackId, packetIndex);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return -1;
}
extern "C" int32_t MP4GetRtpPacketTransmitOffset(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
u_int16_t packetIndex)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->
GetRtpPacketTransmitOffset(hintTrackId, packetIndex);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" bool 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)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->ReadRtpPacket(
hintTrackId, packetIndex,
ppBytes, pNumBytes,
ssrc, includeHeader, includePayload);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" MP4Timestamp MP4GetRtpTimestampStart(
MP4FileHandle hFile,
MP4TrackId hintTrackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetRtpTimestampStart(hintTrackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TIMESTAMP;
}
extern "C" bool MP4SetRtpTimestampStart(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
MP4Timestamp rtpStart)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetRtpTimestampStart(
hintTrackId, rtpStart);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4AddRtpHint(
MP4FileHandle hFile,
MP4TrackId hintTrackId)
{
return MP4AddRtpVideoHint(hFile, hintTrackId, false, 0);
}
extern "C" bool MP4AddRtpVideoHint(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
bool isBframe,
u_int32_t timestampOffset)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->AddRtpHint(hintTrackId,
isBframe, timestampOffset);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4AddRtpPacket(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
bool setMbit,
int32_t transmitOffset)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->AddRtpPacket(
hintTrackId, setMbit, transmitOffset);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4AddRtpImmediateData(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
const u_int8_t* pBytes,
u_int32_t numBytes)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->AddRtpImmediateData(hintTrackId,
pBytes, numBytes);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4AddRtpSampleData(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
MP4SampleId sampleId,
u_int32_t dataOffset,
u_int32_t dataLength)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->AddRtpSampleData(
hintTrackId, sampleId, dataOffset, dataLength);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4AddRtpESConfigurationPacket(
MP4FileHandle hFile,
MP4TrackId hintTrackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->AddRtpESConfigurationPacket(hintTrackId);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4WriteRtpHint(
MP4FileHandle hFile,
MP4TrackId hintTrackId,
MP4Duration duration,
bool isSyncSample)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->WriteRtpHint(
hintTrackId, duration, isSyncSample);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
/* ISMA specific operations */
extern "C" bool MP4MakeIsmaCompliant(
const char* fileName,
u_int32_t verbosity,
bool addIsmaComplianceSdp)
{
MP4File* pFile = NULL;
try {
pFile = new MP4File(verbosity);
pFile->Modify(fileName);
pFile->MakeIsmaCompliant(addIsmaComplianceSdp);
pFile->Close();
delete pFile;
return true;
}
catch (MP4Error* e) {
VERBOSE_ERROR(verbosity, e->Print());
delete e;
}
delete pFile;
return false;
}
extern "C" char* 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)
{
MP4File* pFile = NULL;
try {
pFile = new MP4File(verbosity);
u_int8_t* pBytes = NULL;
u_int64_t numBytes = 0;
pFile->CreateIsmaIodFromParams(
videoProfile,
videoBitrate,
videoConfig,
videoConfigLength,
audioProfile,
audioBitrate,
audioConfig,
audioConfigLength,
&pBytes,
&numBytes);
char* iodBase64 =
MP4ToBase64(pBytes, numBytes);
MP4Free(pBytes);
char* sdpIod =
(char*)MP4Malloc(strlen(iodBase64) + 64);
sprintf(sdpIod,
"a=mpeg4-iod: \042data:application/mpeg4-iod;base64,%s\042",
iodBase64);
MP4Free(iodBase64);
delete pFile;
return sdpIod;
}
catch (MP4Error* e) {
VERBOSE_ERROR(verbosity, e->Print());
delete e;
}
delete pFile;
return NULL;
}
/* Edit list */
extern "C" MP4EditId MP4AddTrackEdit(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId,
MP4Timestamp startTime,
MP4Duration duration,
bool dwell)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
MP4EditId newEditId =
((MP4File*)hFile)->AddTrackEdit(trackId, editId);
if (newEditId != MP4_INVALID_EDIT_ID) {
((MP4File*)hFile)->SetTrackEditMediaStart(
trackId, newEditId, startTime);
((MP4File*)hFile)->SetTrackEditDuration(
trackId, newEditId, duration);
((MP4File*)hFile)->SetTrackEditDwell(
trackId, newEditId, dwell);
}
return newEditId;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_EDIT_ID;
}
extern "C" bool MP4DeleteTrackEdit(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->DeleteTrackEdit(trackId, editId);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" u_int32_t MP4GetTrackNumberOfEdits(
MP4FileHandle hFile,
MP4TrackId trackId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackNumberOfEdits(trackId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return 0;
}
extern "C" MP4Timestamp MP4GetTrackEditMediaStart(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackEditMediaStart(
trackId, editId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_TIMESTAMP;
}
extern "C" MP4Duration MP4GetTrackEditTotalDuration(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackEditTotalDuration(
trackId, editId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_DURATION;
}
extern "C" bool MP4SetTrackEditMediaStart(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId,
MP4Timestamp startTime)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTrackEditMediaStart(
trackId, editId, startTime);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" MP4Duration MP4GetTrackEditDuration(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackEditDuration(trackId, editId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_DURATION;
}
extern "C" bool MP4SetTrackEditDuration(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId,
MP4Duration duration)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTrackEditDuration(trackId, editId, duration);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" int8_t MP4GetTrackEditDwell(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetTrackEditDwell(trackId, editId);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return -1;
}
extern "C" bool MP4SetTrackEditDwell(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4EditId editId,
bool dwell)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
((MP4File*)hFile)->SetTrackEditDwell(trackId, editId, dwell);
return true;
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4ReadSampleFromEditTime(
/* input parameters */
MP4FileHandle hFile,
MP4TrackId trackId,
MP4Timestamp when,
/* output parameters */
u_int8_t** ppBytes,
u_int32_t* pNumBytes,
MP4Timestamp* pStartTime,
MP4Duration* pDuration,
MP4Duration* pRenderingOffset,
bool* pIsSyncSample)
{
MP4SampleId sampleId =
MP4GetSampleIdFromEditTime(
hFile,
trackId,
when,
pStartTime,
pDuration);
return MP4ReadSample(
hFile,
trackId,
sampleId,
ppBytes,
pNumBytes,
NULL,
NULL,
pRenderingOffset,
pIsSyncSample);
}
extern "C" MP4SampleId MP4GetSampleIdFromEditTime(
MP4FileHandle hFile,
MP4TrackId trackId,
MP4Timestamp when,
MP4Timestamp* pStartTime,
MP4Duration* pDuration)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetSampleIdFromEditTime(
trackId, when, pStartTime, pDuration);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return MP4_INVALID_SAMPLE_ID;
}
/* Utlities */
extern "C" char* MP4BinaryToBase16(
const u_int8_t* pData,
u_int32_t dataSize)
{
if (pData || dataSize == 0) {
try {
return MP4ToBase16(pData, dataSize);
}
catch (MP4Error* e) {
delete e;
}
}
return NULL;
}
extern "C" char* MP4BinaryToBase64(
const u_int8_t* pData,
u_int32_t dataSize)
{
if (pData || dataSize == 0) {
try {
return MP4ToBase64(pData, dataSize);
}
catch (MP4Error* e) {
delete e;
}
}
return NULL;
}
/* iTunes meta data handling */
extern "C" bool MP4GetMetadataByIndex(MP4FileHandle hFile, u_int32_t index,
const char** ppName,
u_int8_t** ppValue, u_int32_t* pValueSize)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataByIndex(
index, ppName, ppValue, pValueSize);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4MetadataDelete(MP4FileHandle hFile)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->MetadataDelete();
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataName(MP4FileHandle hFile,
const char* value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataName(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataName(MP4FileHandle hFile,
char** value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataName(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataWriter(MP4FileHandle hFile,
const char* value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataWriter(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataWriter(MP4FileHandle hFile,
char** value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataWriter(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataAlbum(MP4FileHandle hFile,
const char* value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataAlbum(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataAlbum(MP4FileHandle hFile,
char** value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataAlbum(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataArtist(MP4FileHandle hFile,
const char* value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataArtist(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataArtist(MP4FileHandle hFile,
char** value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataArtist(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataTool(MP4FileHandle hFile,
const char* value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataTool(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataTool(MP4FileHandle hFile,
char** value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataTool(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataComment(MP4FileHandle hFile,
const char* value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataComment(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataComment(MP4FileHandle hFile,
char** value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataComment(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataYear(MP4FileHandle hFile,
const char* value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataYear(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataYear(MP4FileHandle hFile,
char** value)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataYear(value);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataTrack(MP4FileHandle hFile,
u_int16_t track, u_int16_t totalTracks)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataTrack(track, totalTracks);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataTrack(MP4FileHandle hFile,
u_int16_t* track, u_int16_t* totalTracks)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataTrack(track, totalTracks);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataDisk(MP4FileHandle hFile,
u_int16_t disk, u_int16_t totalDisks)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataDisk(disk, totalDisks);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataDisk(MP4FileHandle hFile,
u_int16_t* disk, u_int16_t* totalDisks)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataDisk(disk, totalDisks);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataGenre(MP4FileHandle hFile, const char* genre)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataGenre(genre);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataGenre(MP4FileHandle hFile, char** genre)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataGenre(genre);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataTempo(MP4FileHandle hFile, u_int16_t tempo)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataTempo(tempo);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataTempo(MP4FileHandle hFile, u_int16_t* tempo)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataTempo(tempo);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataCompilation(MP4FileHandle hFile, u_int8_t cpl)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataCompilation(cpl);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataCompilation(MP4FileHandle hFile, u_int8_t* cpl)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataCompilation(cpl);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataCoverArt(MP4FileHandle hFile,
u_int8_t *coverArt, u_int32_t size)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataCoverArt(coverArt, size);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataCoverArt(MP4FileHandle hFile,
u_int8_t **coverArt, u_int32_t* size)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataCoverArt(coverArt, size);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4SetMetadataFreeForm(MP4FileHandle hFile, char *name,
u_int8_t* pValue, u_int32_t valueSize)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->SetMetadataFreeForm(name, pValue, valueSize);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}
extern "C" bool MP4GetMetadataFreeForm(MP4FileHandle hFile, char *name,
u_int8_t** pValue, u_int32_t* valueSize)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
return ((MP4File*)hFile)->GetMetadataFreeForm(name, pValue, valueSize);
}
catch (MP4Error* e) {
PRINT_ERROR(e);
delete e;
}
}
return false;
}