Index: mp4file.h===================================================================--- mp4file.h (revision 4)+++ mp4file.h (working copy)@@ -303,6 +303,7 @@ MP4TrackId AddHintTrack(MP4TrackId refTrackId); MP4TrackId AddTextTrack(MP4TrackId refTrackId); MP4TrackId AddChapterTextTrack(MP4TrackId refTrackId);+ MP4TrackId AddSubtitleTrack(MP4TrackId refTrackId); MP4TrackId AddPixelAspectRatio(MP4TrackId trackId, u_int32_t hSpacing, u_int32_t vSpacing);Index: atom_nmhd.cpp===================================================================--- atom_nmhd.cpp (revision 0)+++ atom_nmhd.cpp (revision 0)@@ -0,0 +1,25 @@+/*+ * 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.+ */++#include "mp4common.h"++MP4NmhdAtom::MP4NmhdAtom()+ : MP4Atom("nmhd") +{+ AddVersionAndFlags();+}\ No newline at end of fileIndex: mp4atom.cpp===================================================================--- mp4atom.cpp (revision 4)+++ mp4atom.cpp (working copy)@@ -120,6 +120,8 @@ pAtom = new MP4FreeAtom(); } else if (ATOMID(type) == ATOMID("ftyp")) { pAtom = new MP4FtypAtom();+ } else if (ATOMID(type) == ATOMID("ftab")) {+ pAtom = new MP4FtabAtom(); } break; case 'g':@@ -176,6 +178,8 @@ case 'n': if (ATOMID(type) == ATOMID("name")) { // iTunes pAtom = new MP4NameAtom();+ } else if (ATOMID(type) == ATOMID("nmhd")) {+ pAtom = new MP4NmhdAtom(); } break; case 'r':@@ -216,6 +220,8 @@ case 't': if (ATOMID(type) == ATOMID("text")) { pAtom = new MP4TextAtom();+ } else if (ATOMID(type) == ATOMID("tx3g")) {+ pAtom = new MP4Tx3gAtom(); } else if (ATOMID(type) == ATOMID("tkhd")) { pAtom = new MP4TkhdAtom(); } else if (ATOMID(type) == ATOMID("tfhd")) {Index: mp4.cpp===================================================================--- mp4.cpp (revision 4)+++ mp4.cpp (working copy)@@ -973,6 +973,21 @@ return MP4_INVALID_TRACK_ID; }+extern "C" MP4TrackId MP4AddSubtitleTrack(+ MP4FileHandle hFile, MP4TrackId refTrackId)+{+ if (MP4_IS_VALID_FILE_HANDLE(hFile)) {+ try {+ return ((MP4File*)hFile)->AddSubtitleTrack(refTrackId);+ }+ catch (MP4Error* e) {+ PRINT_ERROR(e);+ delete e;+ }+ }+ return MP4_INVALID_TRACK_ID;+}+ extern "C" MP4TrackId MP4AddChapterTextTrack( MP4FileHandle hFile, MP4TrackId refTrackId) {Index: atom_tx3g.cpp===================================================================--- atom_tx3g.cpp (revision 0)+++ atom_tx3g.cpp (revision 0)@@ -0,0 +1,55 @@+/*+ * 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.+ */++#include "mp4common.h"++MP4Tx3gAtom::MP4Tx3gAtom() + : MP4Atom("tx3g") +{+ AddReserved("reserved1", 4); /* 0 */+ AddReserved("reserved2", 2); /* 1 */++ AddProperty(new MP4Integer16Property("dataReferenceIndex"));/* 2 */++ AddProperty(new MP4Integer32Property("displayFlags")); /* 3 */+ AddProperty(new MP4Integer8Property("horizontalJustification")); /* 4 */+ AddProperty(new MP4Integer8Property("verticalJustification")); /* 5 */++ AddProperty(new MP4Integer8Property("bgColorRed")); /* 6 */+ AddProperty(new MP4Integer8Property("bgColorGreen")); /* 7 */+ AddProperty(new MP4Integer8Property("bgColorBlue")); /* 8 */+ AddProperty(new MP4Integer8Property("bgColorAlpha")); /* 9 */++ AddProperty(new MP4Integer16Property("defTextBoxTop")); /* 10 */+ AddProperty(new MP4Integer16Property("defTextBoxLeft")); /* 11 */+ AddProperty(new MP4Integer16Property("defTextBoxBottom")); /* 12 */+ AddProperty(new MP4Integer16Property("defTextBoxRight")); /* 13 */++ AddProperty(new MP4Integer16Property("startChar")); /* 14 */+ AddProperty(new MP4Integer16Property("endChar")); /* 15 */+ AddProperty(new MP4Integer16Property("fontID")); /* 16 */+ AddProperty(new MP4Integer8Property("fontFace")); /* 17 */+ AddProperty(new MP4Integer8Property("fontSize")); /* 18 */++ AddProperty(new MP4Integer8Property("fontColorRed")); /* 19 */+ AddProperty(new MP4Integer8Property("fontColorGreen")); /* 20 */+ AddProperty(new MP4Integer8Property("fontColorBlue")); /* 21 */+ AddProperty(new MP4Integer8Property("fontColorAlpha")); /* 22 */++ ExpectChildAtom("ftab", Optional, Many);+}Index: atoms.h===================================================================--- atoms.h (revision 4)+++ atoms.h (working copy)@@ -353,6 +353,16 @@ void GenerateGmhdType(); };+class MP4Tx3gAtom : public MP4Atom {+public:+ MP4Tx3gAtom();+};++class MP4FtabAtom : public MP4Atom {+public:+ MP4FtabAtom();+};+ class MP4TfhdAtom : public MP4Atom { public: MP4TfhdAtom();@@ -406,4 +416,9 @@ void Generate(); };+class MP4NmhdAtom : public MP4Atom {+public:+ MP4NmhdAtom();+};+ #endif /* __MP4_ATOMS_INCLUDED__ */Index: atom_ftab.cpp===================================================================--- atom_ftab.cpp (revision 0)+++ atom_ftab.cpp (revision 0)@@ -0,0 +1,32 @@+/*+ * 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.+ */++#include "mp4common.h"++MP4FtabAtom::MP4FtabAtom()+ : MP4Atom("ftab") +{+ MP4Integer16Property* pCount = new MP4Integer16Property("entryCount"); /* 0 */+ AddProperty(pCount);++ MP4TableProperty* pTable = new MP4TableProperty("fontEntries", pCount); /* 1 */+ AddProperty(pTable);++ pTable->AddProperty(new MP4Integer16Property("fontID")); /* 0 */+ pTable->AddProperty(new MP4StringProperty("name", true)); /* 1 */ +}Index: mp4file.cpp===================================================================--- mp4file.cpp (revision 4)+++ mp4file.cpp (working copy)@@ -1948,6 +1948,49 @@ return trackId; }+MP4TrackId MP4File::AddSubtitleTrack(MP4TrackId refTrackId)+{+ // validate reference track id+ FindTrackIndex(refTrackId);++ MP4TrackId trackId = + AddTrack(MP4_TEXT_TRACK_TYPE, GetTrackTimeScale(refTrackId));++ InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "nmhd", 0);++ AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "tx3g");++ MP4StringProperty* pHandlerTypeProperty;+ FindStringProperty(MakeTrackName(trackId, "mdia.hdlr.handlerType"),+ (MP4Property**)&pHandlerTypeProperty);+ pHandlerTypeProperty->SetValue("sbtl");++ // Hardcoded crap... add the ftab atom and add one font entry+ MP4Atom* pFtabAtom = AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.tx3g"), "ftab");++ ((MP4Integer16Property*)pFtabAtom->GetProperty(0))->IncrementValue();++ MP4Integer16Property* pfontID = (MP4Integer16Property*)((MP4TableProperty*)pFtabAtom->GetProperty(1))->GetProperty(0);+ pfontID->AddValue(1);++ MP4StringProperty* pName = (MP4StringProperty*)((MP4TableProperty*)pFtabAtom->GetProperty(1))->GetProperty(1);+ pName->AddValue("Arial");+++ // stsd is a unique beast in that it has a count of the number + // of child atoms that needs to be incremented after we add the text atom+ MP4Integer32Property* pStsdCountProperty;+ FindIntegerProperty(+ MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),+ (MP4Property**)&pStsdCountProperty);+ pStsdCountProperty->IncrementValue();++ /* add the magic "text" atom to the generic media header */+// AddChildAtom(MakeTrackName(trackId, "mdia.minf.gmhd"), "text");++ return trackId;+}+ MP4TrackId MP4File::AddChapterTextTrack(MP4TrackId refTrackId) { // validate reference track idIndex: mp4.h===================================================================--- mp4.h (revision 4)+++ mp4.h (working copy)@@ -553,6 +553,10 @@ MP4FileHandle hFile, MP4TrackId refTrackId);+MP4TrackId MP4AddSubtitleTrack(+ MP4FileHandle hFile,+ MP4TrackId refTrackId);+ MP4TrackId MP4AddPixelAspectRatio( MP4FileHandle hFile, MP4TrackId refTrackId,