status_t MPEG4Writer::start() { if (mFile == NULL) { return UNKNOWN_ERROR; } beginBox("ftyp"); writeFourcc("isom"); writeInt32(0); writeFourcc("isom"); endBox(); mMdatOffset = mOffset; write("\x00\x00\x00\x01mdat????????", 16); for (List<Track *>::iterator it = mTracks.begin(); it != mTracks.end(); ++it) { status_t err = (*it)->start(); if (err != OK) { for (List<Track *>::iterator it2 = mTracks.begin(); it2 != it; ++it2) { (*it2)->stop(); } return err; } } return OK; }
/* * Geodata is stored according to ISO-6709 standard. */ void MPEG4Writer::writeGeoDataBox() { beginBox("\xA9xyz"); /* * For historical reasons, any user data start * with "\0xA9", must be followed by its assoicated * language code. * 0x0012: text string length * 0x15c7: lang (locale) code: en */ writeInt32(0x001215c7); writeLatitude(mLatitudex10000); writeLongitude(mLongitudex10000); writeInt8(0x2F); endBox(); }
void MPEG4Writer::stop() { if (mFile == NULL) { return; } int64_t max_duration = 0; for (List<Track *>::iterator it = mTracks.begin(); it != mTracks.end(); ++it) { (*it)->stop(); int64_t duration = (*it)->getDuration(); if (duration > max_duration) { max_duration = duration; } } // Fix up the size of the 'mdat' chunk. fseek(mFile, mMdatOffset + 8, SEEK_SET); int64_t size = mOffset - mMdatOffset; size = hton64(size); fwrite(&size, 1, 8, mFile); fseek(mFile, mOffset, SEEK_SET); time_t now = time(NULL); beginBox("moov"); beginBox("mvhd"); writeInt32(0); // version=0, flags=0 writeInt32(now); // creation time writeInt32(now); // modification time writeInt32(1000); // timescale writeInt32(max_duration); writeInt32(0x10000); // rate writeInt16(0x100); // volume writeInt16(0); // reserved writeInt32(0); // reserved writeInt32(0); // reserved writeInt32(0x10000); // matrix writeInt32(0); writeInt32(0); writeInt32(0); writeInt32(0x10000); writeInt32(0); writeInt32(0); writeInt32(0); writeInt32(0x40000000); writeInt32(0); // predefined writeInt32(0); // predefined writeInt32(0); // predefined writeInt32(0); // predefined writeInt32(0); // predefined writeInt32(0); // predefined writeInt32(mTracks.size() + 1); // nextTrackID endBox(); // mvhd int32_t id = 1; for (List<Track *>::iterator it = mTracks.begin(); it != mTracks.end(); ++it, ++id) { (*it)->writeTrackHeader(id); } endBox(); // moov CHECK(mBoxes.empty()); fclose(mFile); mFile = NULL; }