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 file Index: 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 id Index: 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,