Here's a patch for mp4v2 I wrote to se in subler.
http://handbrake.fr/pastebin/pastebin.php?show=718
Code: Select all
Index: include/mp4v2/general.h
===================================================================
--- include/mp4v2/general.h (revision 359)
+++ include/mp4v2/general.h (working copy)
@@ -75,6 +75,8 @@
#define MP4_CNTL_TRACK_TYPE "cntl" /**< Constant: control track. */
#define MP4_TEXT_TRACK_TYPE "text" /**< Constant: text track. */
#define MP4_SUBTITLE_TRACK_TYPE "sbtl" /**< Constant: subtitle track. */
+#define MP4_CC_TRACK_TYPE "clcp" /**< Constant: closed captions track. */
+
/*
* This second set of track types should be created
* via MP4AddSystemsTrack(type)
Index: include/mp4v2/track.h
===================================================================
--- include/mp4v2/track.h (revision 359)
+++ include/mp4v2/track.h (working copy)
@@ -309,7 +309,27 @@
uint16_t width,
uint16_t height );
+/** Add a closed caption track.
+ *
+ * MP4AddCCTrack adds a closed caption track track to the mp4 file. MP4WriteSample()
+ * can then be used to add the desired video samples.
+ *
+ * @param hFile handle of file for operation.
+ * @param timeScale the timescale in ticks per second of the track.
+ * @param width specifies the video frame width in pixels.
+ * @param height specifies the video frame height in pixels.
+ *
+ * @return On success, the track-id of the new track.
+ * On error, #MP4_INVALID_TRACK_ID.
+ */
MP4V2_EXPORT
+MP4TrackId MP4AddCCTrack(
+ MP4FileHandle hFile,
+ uint32_t timeScale,
+ uint16_t width,
+ uint16_t height );
+
+MP4V2_EXPORT
MP4TrackId MP4AddPixelAspectRatio(
MP4FileHandle hFile,
MP4TrackId refTrackId,
Index: GNUmakefile.am
===================================================================
--- GNUmakefile.am (revision 359)
+++ GNUmakefile.am (working copy)
@@ -16,6 +16,7 @@
src/atom_amr.cpp \
src/atom_avc1.cpp \
src/atom_avcC.cpp \
+ src/atom_c608.cpp \
src/atom_chpl.cpp \
src/atom_colr.cpp \
src/atom_d263.cpp \
Index: src/atom_c608.cpp
===================================================================
--- src/atom_c608.cpp (revision 0)
+++ src/atom_c608.cpp (revision 0)
@@ -0,0 +1,46 @@
+/*
+ * 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 "src/impl.h"
+
+namespace mp4v2 {
+namespace impl {
+
+///////////////////////////////////////////////////////////////////////////////
+
+MP4C608Atom::MP4C608Atom()
+ : MP4Atom("c608")
+{
+ AddReserved("reserved1", 4); /* 0 */
+ AddReserved("reserved2", 2); /* 1 */
+
+ AddProperty(new MP4Integer16Property("dataReferenceIndex")); /* 2 */
+}
+
+void MP4C608Atom::Generate()
+{
+ // generate children
+ MP4Atom::Generate();
+
+ ((MP4Integer16Property*)m_pProperties[2])->SetValue(1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+}
+} // namespace mp4v2::impl
Index: src/mp4file.h
===================================================================
--- src/mp4file.h (revision 359)
+++ src/mp4file.h (working copy)
@@ -387,6 +387,10 @@
MP4TrackId AddSubtitleTrack(uint32_t timescale,
uint16_t width,
uint16_t height);
+
+ MP4TrackId AddCCTrack(uint32_t timeScale,
+ uint16_t width,
+ uint16_t height);
MP4TrackId AddPixelAspectRatio(MP4TrackId trackId, uint32_t hSpacing, uint32_t vSpacing);
MP4TrackId AddColr(MP4TrackId trackId, uint16_t pri, uint16_t tran, uint16_t mat);
Index: src/mp4atom.cpp
===================================================================
--- src/mp4atom.cpp (revision 359)
+++ src/mp4atom.cpp (working copy)
@@ -849,6 +849,8 @@
break;
case 'c':
+ if( ATOMID(type) == ATOMID("c608") )
+ return new MP4C608Atom();
if( ATOMID(type) == ATOMID("chap") )
return new MP4TrefTypeAtom( type );
if( ATOMID(type) == ATOMID("chpl") )
Index: src/mp4.cpp
===================================================================
--- src/mp4.cpp (revision 359)
+++ src/mp4.cpp (working copy)
@@ -1173,6 +1173,23 @@
}
return MP4_INVALID_TRACK_ID;
}
+
+ MP4TrackId MP4AddCCTrack(MP4FileHandle hFile,
+ uint32_t timeScale,
+ uint16_t width,
+ uint16_t height)
+ {
+ if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
+ try {
+ return ((MP4File*)hFile)->AddCCTrack(timeScale, width, height);
+ }
+ catch (MP4Error* e) {
+ PRINT_ERROR(e);
+ delete e;
+ }
+ }
+ return MP4_INVALID_TRACK_ID;
+ }
MP4TrackId MP4AddChapterTextTrack(
MP4FileHandle hFile, MP4TrackId refTrackId, uint32_t timescale)
Index: src/atoms.h
===================================================================
--- src/atoms.h (revision 359)
+++ src/atoms.h (working copy)
@@ -398,6 +398,12 @@
void Generate();
};
+class MP4C608Atom : public MP4Atom {
+public:
+ MP4C608Atom();
+ void Generate();
+};
+
class MP4FtabAtom : public MP4Atom {
public:
MP4FtabAtom();
Index: src/mp4file.cpp
===================================================================
--- src/mp4file.cpp (revision 359)
+++ src/mp4file.cpp (working copy)
@@ -2095,6 +2095,31 @@
return trackId;
}
+MP4TrackId MP4File::AddCCTrack(uint32_t timeScale,
+ uint16_t width,
+ uint16_t height)
+ {
+ MP4TrackId trackId =
+ AddTrack(MP4_CC_TRACK_TYPE, timeScale);
+
+ InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "nmhd", 0);
+
+ AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "c608");
+
+ SetTrackFloatProperty(trackId, "tkhd.width", width);
+ SetTrackFloatProperty(trackId, "tkhd.height", height);
+
+ // 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 tx3g atom
+ MP4Integer32Property* pStsdCountProperty;
+ FindIntegerProperty(
+ MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
+ (MP4Property**)&pStsdCountProperty);
+ pStsdCountProperty->IncrementValue();
+
+ return trackId;
+ }
+
MP4TrackId MP4File::AddChapterTextTrack(MP4TrackId refTrackId, uint32_t timescale)
{
// validate reference track id
The samples have to be wrapped inside a cdat atom. I don't think the timecode track is necessary, I created some without it and they worked.
But I didn't really do much testing.