From: PacketVideo CM Date: Wed, 21 Oct 2009 16:46:39 +0000 (-0700) Subject: RIO-7563: Adding support for authoring moof clips for live sessions in mo4 composer... X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=14c84393299292216c78c3862b6955ae0b7b03f1;p=android-x86%2Fexternal-opencore.git RIO-7563: Adding support for authoring moof clips for live sessions in mo4 composer library. --- diff --git a/engines/2way/src/pv_2way_sdkinfo.h b/engines/2way/src/pv_2way_sdkinfo.h index e90e47a9..e899a0d0 100644 --- a/engines/2way/src/pv_2way_sdkinfo.h +++ b/engines/2way/src/pv_2way_sdkinfo.h @@ -21,7 +21,7 @@ // This header file is automatically generated at build-time // *** OFFICIAL RELEASE INFO -- Will not auto update -#define PV2WAY_ENGINE_SDKINFO_LABEL "1022083" +#define PV2WAY_ENGINE_SDKINFO_LABEL "1022110" #define PV2WAY_ENGINE_SDKINFO_DATE 0x20091015 #endif //PV_2WAY_SDKINFO_H_INCLUDED diff --git a/engines/author/src/pv_author_sdkinfo.h b/engines/author/src/pv_author_sdkinfo.h index fba8a549..1c9687b4 100644 --- a/engines/author/src/pv_author_sdkinfo.h +++ b/engines/author/src/pv_author_sdkinfo.h @@ -21,7 +21,7 @@ // This header file is automatically generated at build-time // *** OFFICIAL RELEASE INFO -- Will not auto update -#define PVAUTHOR_ENGINE_SDKINFO_LABEL "1022083" +#define PVAUTHOR_ENGINE_SDKINFO_LABEL "1022110" #define PVAUTHOR_ENGINE_SDKINFO_DATE 0x20091015 #endif //PV_AUTHOR_SDKINFO_H_INCLUDED diff --git a/engines/player/src/pv_player_sdkinfo.h b/engines/player/src/pv_player_sdkinfo.h index fea6c03a..00faa873 100644 --- a/engines/player/src/pv_player_sdkinfo.h +++ b/engines/player/src/pv_player_sdkinfo.h @@ -21,7 +21,7 @@ // This header file is automatically generated at build-time // *** OFFICIAL RELEASE INFO -- Will not auto update -#define PVPLAYER_ENGINE_SDKINFO_LABEL "1022083" +#define PVPLAYER_ENGINE_SDKINFO_LABEL "1022110" #define PVPLAYER_ENGINE_SDKINFO_DATE 0x20091015 #endif //PV_PLAYER_SDKINFO_H_INCLUDED diff --git a/fileformats/mp4/composer/include/a_atomdefs.h b/fileformats/mp4/composer/include/a_atomdefs.h index dc0385f6..a8e11fea 100644 --- a/fileformats/mp4/composer/include/a_atomdefs.h +++ b/fileformats/mp4/composer/include/a_atomdefs.h @@ -277,7 +277,9 @@ typedef enum //b1 is set - Meta data is upfront, this implies temp files are needed while authoring //b2 - undefined //b3 is set - Do not use temp files while authoring -//b4-b31 - Reserved for future use +//b6 is set - Movie fragment mode +//b7 is set - Live movie fragment mode +//b8-b31 - Reserved for future use /** * This mode authors non Progressive Downloadable output files using temp files @@ -313,6 +315,10 @@ typedef enum // 6th bit is now reserved movie fragment mode and last bit is reserved for interleaving #define PVMP4FF_MOVIE_FRAGMENT_MODE 0x00000021 +// live movie fragment mode +// For authoring open-ended sessions for live streaming +#define PVMP4FF_LIVE_MOVIE_FRAGMENT_MODE 0x00000061 + #define DEFAULT_MOVIE_FRAGMENT_DURATION_IN_MS 10000 class PVMP4FFComposerSampleParam diff --git a/fileformats/mp4/composer/include/a_impeg4file.h b/fileformats/mp4/composer/include/a_impeg4file.h index c29cb0ca..aeba40b6 100644 --- a/fileformats/mp4/composer/include/a_impeg4file.h +++ b/fileformats/mp4/composer/include/a_impeg4file.h @@ -301,6 +301,7 @@ class PVA_FF_IMpeg4File : public PVA_FF_ISucceedFail virtual void setTargetBitrate(uint32 trackID, uint32 avgBitRate, uint32 maxBitRate = 0, uint32 bufferSizeDB = 0) = 0; virtual void setTimeScale(uint32 trackID, uint32 rate) = 0; virtual void setMaxBufferSizeDB(uint32 trackID, uint32 max) = 0; + virtual bool setTrackDuration(uint32 trackID, uint64 duration) = 0; virtual void setMajorBrand(uint32 brand = BRAND_3GPP4) = 0; virtual void setMajorBrandVersion(uint32 version = VERSION_3GPP4) = 0; diff --git a/fileformats/mp4/composer/include/mediaatom.h b/fileformats/mp4/composer/include/mediaatom.h index d73729f8..ed11ae35 100644 --- a/fileformats/mp4/composer/include/mediaatom.h +++ b/fileformats/mp4/composer/include/mediaatom.h @@ -39,6 +39,7 @@ class PVA_FF_MediaAtom : public PVA_FF_Atom // parameter is ignored - hence the default parameter value. PVA_FF_MediaAtom(int32 mediaType, int32 codecType, + uint8 version, uint32 fileAuthoringFlags, uint32 protocol = 0, uint8 profile = 1, diff --git a/fileformats/mp4/composer/include/mediaheaderatom.h b/fileformats/mp4/composer/include/mediaheaderatom.h index 5a51c758..1970dac8 100644 --- a/fileformats/mp4/composer/include/mediaheaderatom.h +++ b/fileformats/mp4/composer/include/mediaheaderatom.h @@ -30,15 +30,15 @@ class PVA_FF_MediaHeaderAtom : public PVA_FF_FullAtom { public: - PVA_FF_MediaHeaderAtom(); // Constructor + PVA_FF_MediaHeaderAtom(uint8 version); // Constructor virtual ~PVA_FF_MediaHeaderAtom(); // Creation Time gets and sets - void setCreationTime(uint32 ct) + void setCreationTime(uint64 ct) { _creationTime = ct; } - uint32 getCreationTime() const + uint64 getCreationTime() const { return _creationTime; } @@ -64,11 +64,11 @@ class PVA_FF_MediaHeaderAtom : public PVA_FF_FullAtom } // Duration gets and sets - void setDuration(uint32 d) + void setDuration(uint64 d) { _duration = d; } - uint32 getDuration() const + uint64 getDuration() const { return _duration; } @@ -93,10 +93,10 @@ class PVA_FF_MediaHeaderAtom : public PVA_FF_FullAtom void init(); virtual void recomputeSize(); - uint32 _creationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now - uint32 _modificationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now + uint64 _creationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now + uint64 _modificationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now uint32 _timeScale; // 4 (32bits) - uint32 _duration; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now + uint64 _duration; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now uint16 _language; // Actually 3 5-bit objects representing the packed ISO-639-2/T language code // Rendered as 15 bits with the leading pad bit from above. diff --git a/fileformats/mp4/composer/include/movieatom.h b/fileformats/mp4/composer/include/movieatom.h index 20a0b419..8a50fa3e 100644 --- a/fileformats/mp4/composer/include/movieatom.h +++ b/fileformats/mp4/composer/include/movieatom.h @@ -57,7 +57,7 @@ class PVA_FF_MovieAtom : public PVA_FF_Atom, public PVA_FF_ISucceedFail virtual ~PVA_FF_MovieAtom(); // Get the duration of the movie - uint32 getDuration() + uint64 getDuration() { return _pmovieHeaderAtom->getDuration(); } @@ -337,7 +337,7 @@ class PVA_FF_MovieAtom : public PVA_FF_Atom, public PVA_FF_ISucceedFail } // Movie Fragment : add movie extend atom usage APIs - void setMovieFragmentDuration(); + void setMovieFragmentDuration(uint32 movieFragmentDuration); void updateMovieFragmentDuration(uint32 trackID, uint32 ts); void writeMovieFragmentDuration(MP4_AUTHOR_FF_FILE_IO_WRAP* fp); void SetMaxSampleSize(uint32, uint32); @@ -371,6 +371,7 @@ class PVA_FF_MovieAtom : public PVA_FF_Atom, public PVA_FF_ISucceedFail // Movie Fragment : Atoms needed in movie fragment mode PVA_FF_MovieExtendsAtom *_pMovieExtendsAtom; bool _oMovieFragmentEnabled; + bool _oLiveMovieFragmentEnabled; }; diff --git a/fileformats/mp4/composer/include/movieheaderatom.h b/fileformats/mp4/composer/include/movieheaderatom.h index 5a2c2c4a..da24ccab 100644 --- a/fileformats/mp4/composer/include/movieheaderatom.h +++ b/fileformats/mp4/composer/include/movieheaderatom.h @@ -35,11 +35,11 @@ class PVA_FF_MovieHeaderAtom : public PVA_FF_FullAtom virtual ~PVA_FF_MovieHeaderAtom(); // Creation Time gets and sets - may not need to have the set method public! - void setCreationTime(uint32 ct) + void setCreationTime(uint64 ct) { _creationTime = ct; } - uint32 getCreationTime() const + uint64 getCreationTime() const { return _creationTime; } @@ -65,7 +65,7 @@ class PVA_FF_MovieHeaderAtom : public PVA_FF_FullAtom } // Duration gets and sets - void setDuration(uint32 d) + void setDuration(uint64 d) { if (d > _duration) { @@ -73,7 +73,7 @@ class PVA_FF_MovieHeaderAtom : public PVA_FF_FullAtom } } - uint32 getDuration() const + uint64 getDuration() const { return _duration; } @@ -98,10 +98,10 @@ class PVA_FF_MovieHeaderAtom : public PVA_FF_FullAtom private: - uint32 _creationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits (version 0) for now - uint32 _modificationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now + uint64 _creationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits (version 0) for now + uint64 _modificationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now uint32 _timeScale; // 4 (32bits) - uint32 _duration; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now + uint64 _duration; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now uint32 _nextTrackID; // 4 (32 bits) diff --git a/fileformats/mp4/composer/include/mpeg4file.h b/fileformats/mp4/composer/include/mpeg4file.h index df5100af..25f4a0be 100644 --- a/fileformats/mp4/composer/include/mpeg4file.h +++ b/fileformats/mp4/composer/include/mpeg4file.h @@ -201,6 +201,7 @@ class PVA_FF_Mpeg4File : public PVA_FF_IMpeg4File, public PVA_FF_Parentable void addTrackReference(uint32 currtrackID, int32 reftrackID); void setTargetBitrate(uint32 trackID, uint32 avgBitRate, uint32 maxBitRate = 0, uint32 bufferSizeDB = 0); void setTimeScale(uint32 trackID, uint32 rate); + bool setTrackDuration(uint32 trackID, uint64 duration); // An access function to set the output path string for PVA_FF_MediaDataAtom objects virtual void SetTempOutputPath(PVA_FF_UNICODE_STRING_PARAM outputPath); @@ -385,6 +386,7 @@ class PVA_FF_Mpeg4File : public PVA_FF_IMpeg4File, public PVA_FF_Parentable uint32 _fileAuthoringFlags; bool _oInterLeaveEnabled; bool _oMovieAtomUpfront; + bool _oLiveMovieFragmentEnabled; uint32 _interLeaveDuration; // Always in milliseconds diff --git a/fileformats/mp4/composer/include/trackatom.h b/fileformats/mp4/composer/include/trackatom.h index fa75ac87..1b551aa7 100644 --- a/fileformats/mp4/composer/include/trackatom.h +++ b/fileformats/mp4/composer/include/trackatom.h @@ -51,6 +51,7 @@ class PVA_FF_TrackAtom : public PVA_FF_Atom, public PVA_FF_ISucceedFail // parameter is ignored - hence the default parameter value. PVA_FF_TrackAtom(int32 type, uint32 id, + uint8 version, uint32 fileAuthoringFlags, int32 codecType = 0, uint32 protocol = 0, @@ -150,7 +151,7 @@ class PVA_FF_TrackAtom : public PVA_FF_Atom, public PVA_FF_ISucceedFail _pmediaAtom->setLanguage(language); } - uint32 getDuration() const + uint64 getDuration() const { return _ptrackHeader->getDuration(); } diff --git a/fileformats/mp4/composer/include/trackheaderatom.h b/fileformats/mp4/composer/include/trackheaderatom.h index b1c2fb9f..c5c3d14e 100644 --- a/fileformats/mp4/composer/include/trackheaderatom.h +++ b/fileformats/mp4/composer/include/trackheaderatom.h @@ -49,21 +49,21 @@ class PVA_FF_TrackHeaderAtom : public PVA_FF_FullAtom } // Creation Time gets and sets - void setCreationTime(uint32 ct) + void setCreationTime(uint64 ct) { _creationTime = ct; } - uint32 getCreationTime() const + uint64 getCreationTime() const { return _creationTime; } // Modification Time gets and sets - void setModificationTime(uint32 mt) + void setModificationTime(uint64 mt) { _modificationTime = mt; } - uint32 getModificationTime() const + uint64 getModificationTime() const { return _modificationTime; } @@ -79,15 +79,15 @@ class PVA_FF_TrackHeaderAtom : public PVA_FF_FullAtom } // Duration gets and sets - void setDuration(uint32 d) + void setDuration(uint64 d) { _duration = d; } - uint32 getDuration() const + uint64 getDuration() const { - uint32 total_duration = 0; + uint64 total_duration = 0; total_duration = (_duration + _deltaTS); - if (!total_duration) + if (total_duration == 0) total_duration = _currTrackDuration; return total_duration; @@ -112,13 +112,13 @@ class PVA_FF_TrackHeaderAtom : public PVA_FF_FullAtom int32 _mediaType; - uint32 _creationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now - uint32 _modificationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now + uint64 _creationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now + uint64 _modificationTime; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now uint32 _trackID; // 4 (32bits) uint32 _reserved1; // = 0; - uint32 _duration; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now + uint64 _duration; // 4/8 (32/64bits) -- Will templatize later - using 32bits for now // Static reserved constants uint32 _reserved2[3]; // = { 0, 0, 0 }; diff --git a/fileformats/mp4/composer/src/mediaatom.cpp b/fileformats/mp4/composer/src/mediaatom.cpp index ceda6f4a..b235428a 100644 --- a/fileformats/mp4/composer/src/mediaatom.cpp +++ b/fileformats/mp4/composer/src/mediaatom.cpp @@ -29,6 +29,7 @@ // Constructor PVA_FF_MediaAtom::PVA_FF_MediaAtom(int32 mediaType, int32 codecType, + uint8 version, uint32 fileAuthoringFlags, uint32 protocol, uint8 profile, @@ -37,7 +38,7 @@ PVA_FF_MediaAtom::PVA_FF_MediaAtom(int32 mediaType, : PVA_FF_Atom(MEDIA_ATOM) { - PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MediaHeaderAtom, (), _pmediaHeader); + PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MediaHeaderAtom, (version), _pmediaHeader); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_HandlerAtom, (mediaType, (uint8)0, (uint8)0), _phandler); diff --git a/fileformats/mp4/composer/src/mediaheaderatom.cpp b/fileformats/mp4/composer/src/mediaheaderatom.cpp index 02506429..10e1a6dc 100644 --- a/fileformats/mp4/composer/src/mediaheaderatom.cpp +++ b/fileformats/mp4/composer/src/mediaheaderatom.cpp @@ -26,10 +26,12 @@ #include "mediaheaderatom.h" #include "atomutils.h" #include "a_atomdefs.h" +#include "oscl_int64_utils.h" + // Constructor -PVA_FF_MediaHeaderAtom::PVA_FF_MediaHeaderAtom() - : PVA_FF_FullAtom(MEDIA_HEADER_ATOM, 0, 0) +PVA_FF_MediaHeaderAtom::PVA_FF_MediaHeaderAtom(uint8 version) + : PVA_FF_FullAtom(MEDIA_HEADER_ATOM, version, 0) { init(); // Initialize all member variables recomputeSize(); @@ -46,8 +48,12 @@ PVA_FF_MediaHeaderAtom::~PVA_FF_MediaHeaderAtom() void PVA_FF_MediaHeaderAtom::init() { - PVA_FF_AtomUtils::setTime(_creationTime); // Setting creating time (since 1/1/1970) - NEED FIX to 1/1/1904 - PVA_FF_AtomUtils::setTime(_modificationTime); // Setting modification time + // use a temporary variable to set the current time since the API setTime takes uint32 parameters + uint32 timeSet; + PVA_FF_AtomUtils::setTime(timeSet); // Setting creating time (since 1/1/1970) - NEED FIX to 1/1/1904 + _creationTime = timeSet; + PVA_FF_AtomUtils::setTime(timeSet); // Setting modification time + _modificationTime = timeSet; _timeScale = DEFAULT_PRESENTATION_TIMESCALE; _duration = 0; _language = 0; // Until find better default value @@ -92,10 +98,22 @@ void PVA_FF_MediaHeaderAtom::recomputeSize() { int32 size = getDefaultSize(); // Get size of base class members - size += 4; // creationTime - size += 4; // modificationTime - size += 4; // timeScale - size += 4; // duration + + // Fields that vary depending on the version + if (getVersion() == 0) + { + size += 4; //_creationTime + size += 4; //_modificationTime + size += 4; //_timeScale + size += 4; //_duration + } + else // getVersion() == 1 + { + size += 8; //_creationTime + size += 8; //_modificationTime + size += 4; //_timeScale + size += 8; //_duration + } size += 2; // language size += 2; // reserved @@ -122,14 +140,33 @@ PVA_FF_MediaHeaderAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) } rendered += getDefaultSize(); - if (!PVA_FF_AtomUtils::render32(fp, getCreationTime())) + if (getVersion() == 0) { - return false; + if (!PVA_FF_AtomUtils::render32(fp, + Oscl_Int64_Utils::get_uint64_lower32(getCreationTime()))) + { + return false; + } + + if (!PVA_FF_AtomUtils::render32(fp, + Oscl_Int64_Utils::get_uint64_lower32(getModificationTime()))) + + { + return false; + } } - if (!PVA_FF_AtomUtils::render32(fp, getModificationTime())) + else // getVersion() == 1 { - return false; + if (!PVA_FF_AtomUtils::render64(fp, getCreationTime())) + { + return false; + } + if (!PVA_FF_AtomUtils::render64(fp, getModificationTime())) + { + return false; + } } + if (!PVA_FF_AtomUtils::render32(fp, getTimeScale())) { return false; @@ -139,13 +176,32 @@ PVA_FF_MediaHeaderAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) * To ensure that the total track duration includes the duration of the * last sample as well, which in our case fp same as the last but one. */ - uint32 totalDuration = getDuration() + _deltaTS; + uint64 totalDuration = getDuration() + _deltaTS; - if (!PVA_FF_AtomUtils::render32(fp, totalDuration)) + if (getVersion() == 0) { - return false; + if (!PVA_FF_AtomUtils::render32(fp, + Oscl_Int64_Utils::get_uint64_lower32(totalDuration))) + { + return false; + } + } + else // getVersion() == 1 + { + if (!PVA_FF_AtomUtils::render64(fp, totalDuration)) + { + return false; + } + } + + if (getVersion() == 0) + { + rendered += 16; + } + else + { + rendered += 28; } - rendered += 16; if (!PVA_FF_AtomUtils::render16(fp, getLanguage())) { diff --git a/fileformats/mp4/composer/src/movieatom.cpp b/fileformats/mp4/composer/src/movieatom.cpp index bb884097..185e83d4 100644 --- a/fileformats/mp4/composer/src/movieatom.cpp +++ b/fileformats/mp4/composer/src/movieatom.cpp @@ -56,6 +56,7 @@ PVA_FF_MovieAtom::PVA_FF_MovieAtom(uint32 fileAuthoringFlags) _pAssetInfoKeyRecordingYearAtom = NULL; _oMovieFragmentEnabled = false; + _pMovieExtendsAtom = NULL; //Movie Fragment : Enable movie fragment mode and create movie extends atom if ((fileAuthoringFlags & PVMP4FF_MOVIE_FRAGMENT_MODE) == (PVMP4FF_MOVIE_FRAGMENT_MODE)) { @@ -64,7 +65,20 @@ PVA_FF_MovieAtom::PVA_FF_MovieAtom(uint32 fileAuthoringFlags) } - PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MovieHeaderAtom, ((uint8)0, (uint32)0, fileAuthoringFlags), _pmovieHeaderAtom); + _oLiveMovieFragmentEnabled = false; + // Live movie fragment mode + // Note, this mode implies PVMP4FF_MOVIE_FRAGMENT_MODE, so both _oMovieFragmentEnabled and + // _oLiveMovieFragmentEnabled will be set to true + if ((fileAuthoringFlags & PVMP4FF_LIVE_MOVIE_FRAGMENT_MODE) == PVMP4FF_LIVE_MOVIE_FRAGMENT_MODE) + { + _oLiveMovieFragmentEnabled = true; + } + + // Use version 1 of the FullBox spec only when PVMP4FF_LIVE_MOVIE_FRAGMENT_MODE is enabled + uint8 movieHeaderVersion = 0; + if (_oLiveMovieFragmentEnabled) + movieHeaderVersion = 1; + PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MovieHeaderAtom, (movieHeaderVersion, (uint32)0, fileAuthoringFlags), _pmovieHeaderAtom); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtomVecType, (), _pMediaTrackVec); @@ -234,7 +248,9 @@ PVA_FF_MovieAtom::recomputeSize() if (_puserDataAtom != NULL) { - if (_puserDataAtom->getUserDataAtomVecSize() > 0) + + if ((_puserDataAtom->getUserDataAtomVecSize() > 0) + && !(_oLiveMovieFragmentEnabled)) { size += _puserDataAtom->getSize(); } @@ -244,7 +260,8 @@ PVA_FF_MovieAtom::recomputeSize() { for (uint32 i = 0; i < _pMediaTrackVec->size(); i++) { - if ((*_pMediaTrackVec)[i]->getSampleCount() > 0) + if (((*_pMediaTrackVec)[i]->getSampleCount() > 0) + || (_oLiveMovieFragmentEnabled)) { size += (*_pMediaTrackVec)[i]->getSize(); } @@ -270,10 +287,10 @@ PVA_FF_MovieAtom::recomputeSize() void PVA_FF_MovieAtom::prepareToRender() { - uint32 maxTrackDuration = 0; + uint64 maxTrackDuration = 0; - uint32 creationTime = _pmovieHeaderAtom->getCreationTime(); - uint32 modTime = _pmovieHeaderAtom->getModificationTime(); + uint64 creationTime = _pmovieHeaderAtom->getCreationTime(); + uint64 modTime = _pmovieHeaderAtom->getModificationTime(); if (_pMediaTrackVec != NULL) { @@ -291,7 +308,7 @@ PVA_FF_MovieAtom::prepareToRender() track->prepareToRender(); - uint32 TrackDuration = track->getDuration(); + uint64 TrackDuration = track->getDuration(); if (TrackDuration > maxTrackDuration) { @@ -334,7 +351,10 @@ PVA_FF_MovieAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) { if (_puserDataAtom != NULL) { - if (_puserDataAtom->getUserDataAtomVecSize() > 0) + // Don't render user data atoms when the live movie + // fragment mode is enabled + if ((_puserDataAtom->getUserDataAtomVecSize() > 0) + && !(_oLiveMovieFragmentEnabled)) { if (!_puserDataAtom->renderToFileStream(fp)) { @@ -348,7 +368,10 @@ PVA_FF_MovieAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) { for (uint32 i = 0; i < _pMediaTrackVec->size(); i++) { - if ((*_pMediaTrackVec)[i]->getSampleCount() > 0) + // Render track information when there are samples available + // or the mode PVMP4FF_LIVE_MOVIE_FRAGMENT_MODE is enabled + if (((*_pMediaTrackVec)[i]->getSampleCount() > 0) + || (_oLiveMovieFragmentEnabled)) { if (!((*_pMediaTrackVec)[i]->renderToFileStream(fp))) { @@ -660,11 +683,16 @@ PVA_FF_MovieAtom::createAssetInfoAtoms() // functions to set and update fragment duration in MVEX atom void -PVA_FF_MovieAtom::setMovieFragmentDuration() +PVA_FF_MovieAtom::setMovieFragmentDuration(uint32 movieFragmentDuration) { + if (_pMovieExtendsAtom != NULL) + { + // fragment duration is specified in milliseconds. Convert it to + // the presentation timescale + uint32 movieFragmentDur = (uint32)(((float)(movieFragmentDuration) * getTimeScale()) / 1000); + _pMovieExtendsAtom->setMovieFragmentDuration(movieFragmentDur); - _pMovieExtendsAtom->setMovieFragmentDuration(getDuration()); - + } } diff --git a/fileformats/mp4/composer/src/movieheaderatom.cpp b/fileformats/mp4/composer/src/movieheaderatom.cpp index f4853be8..0b52b2dc 100644 --- a/fileformats/mp4/composer/src/movieheaderatom.cpp +++ b/fileformats/mp4/composer/src/movieheaderatom.cpp @@ -26,6 +26,7 @@ #include "movieheaderatom.h" #include "atomutils.h" #include "a_atomdefs.h" +#include "oscl_int64_utils.h" // Constructor @@ -34,8 +35,12 @@ PVA_FF_MovieHeaderAtom::PVA_FF_MovieHeaderAtom(uint8 version, uint32 flags, uint { OSCL_UNUSED_ARG(fileAuthoringFlags); - PVA_FF_AtomUtils::setTime(_creationTime); // Setting creating time (since 1/1/1904) - PVA_FF_AtomUtils::setTime(_modificationTime); // Setting modification time + // use a temporary variable to set the current time since the API setTime takes uint32 parameters + uint32 timeSet; + PVA_FF_AtomUtils::setTime(timeSet); // Setting creating time (since 1/1/1904) + _creationTime = timeSet; + PVA_FF_AtomUtils::setTime(timeSet); // Setting modification time + _modificationTime = timeSet; _timeScale = DEFAULT_PRESENTATION_TIMESCALE; _duration = 0; _nextTrackID = INITIAL_TRACK_ID; @@ -61,10 +66,22 @@ void PVA_FF_MovieHeaderAtom::recomputeSize() { int32 size = getDefaultSize(); // Default size of PVA_FF_FullAtom class - size += sizeof(_creationTime); // Sizes of member variables - size += sizeof(_modificationTime); - size += sizeof(_timeScale); - size += sizeof(_duration); + + // Fields that vary depending on the version + if (getVersion() == 0) + { + size += 4; //_creationTime + size += 4; //_modificationTime + size += 4; //_timeScale + size += 4; //_duration + } + else // getVersion() == 1 + { + size += 8; //_creationTime + size += 8; //_modificationTime + size += 4; //_timeScale + size += 8; //_duration + } size += 76; // Size of combined reserved words @@ -119,14 +136,34 @@ PVA_FF_MovieHeaderAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) } rendered += getDefaultSize(); - if (!PVA_FF_AtomUtils::render32(fp, getCreationTime())) + if (getVersion() == 0) { - return false; + if (!PVA_FF_AtomUtils::render32(fp, + Oscl_Int64_Utils::get_uint64_lower32(getCreationTime()))) + { + return false; + } + + if (!PVA_FF_AtomUtils::render32(fp, + Oscl_Int64_Utils::get_uint64_lower32(getModificationTime()))) + + { + return false; + } } - if (!PVA_FF_AtomUtils::render32(fp, getModificationTime())) + else // getVersion() == 1 { - return false; + if (!PVA_FF_AtomUtils::render64(fp, getCreationTime())) + { + return false; + } + if (!PVA_FF_AtomUtils::render64(fp, getModificationTime())) + { + return false; + } } + + if (!PVA_FF_AtomUtils::render32(fp, getTimeScale())) { return false; @@ -137,12 +174,32 @@ PVA_FF_MovieHeaderAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) * last sample as well, which in our case fp same as the last but one. */ //uint32 totalDuration = getDuration() + _deltaTS; - uint32 totalDuration = getDuration(); - if (!PVA_FF_AtomUtils::render32(fp, totalDuration)) + uint64 totalDuration = getDuration(); + + if (getVersion() == 0) { - return false; + if (!PVA_FF_AtomUtils::render32(fp, + Oscl_Int64_Utils::get_uint64_lower32(totalDuration))) + { + return false; + } + } + else // getVersion() == 1 + { + if (!PVA_FF_AtomUtils::render64(fp, totalDuration)) + { + return false; + } + } + + if (getVersion() == 0) + { + rendered += 16; + } + else + { + rendered += 28; } - rendered += 16; uint32 reserved = 0x00010000; if (!PVA_FF_AtomUtils::render32(fp, reserved)) diff --git a/fileformats/mp4/composer/src/mpeg4file.cpp b/fileformats/mp4/composer/src/mpeg4file.cpp index eb80c573..d93a4c38 100644 --- a/fileformats/mp4/composer/src/mpeg4file.cpp +++ b/fileformats/mp4/composer/src/mpeg4file.cpp @@ -114,6 +114,7 @@ PVA_FF_Mpeg4File::PVA_FF_Mpeg4File(int32 mediaType) _oIsFileOpen = false; _pInterLeaveBufferVec = NULL; _oInterLeaveEnabled = false; + _oLiveMovieFragmentEnabled = false; _aFs = NULL; } @@ -221,6 +222,7 @@ PVA_FF_Mpeg4File::init(int32 mediaType, // Movie Fragments flags initialised _oMovieFragmentEnabled = false; + _oLiveMovieFragmentEnabled = false; _oComposeMoofAtom = false; _movieFragmentDuration = DEFAULT_MOVIE_FRAGMENT_DURATION_IN_MS; _pCurrentMoofAtom = NULL; @@ -289,6 +291,14 @@ PVA_FF_Mpeg4File::init(int32 mediaType, _oUserDataUpFront = false; } + // Live movie fragment mode + // Note, this mode implies PVMP4FF_MOVIE_FRAGMENT_MODE, so both _oMovieFragmentEnabled and + // _oLiveMovieFragmentEnabled will be set to true + if ((fileAuthoringFlags & PVMP4FF_LIVE_MOVIE_FRAGMENT_MODE) == PVMP4FF_LIVE_MOVIE_FRAGMENT_MODE) + { + _oLiveMovieFragmentEnabled = true; + } + // Create user data atom PV_MP4_FF_NEW(fp->auditCB, PVA_FF_UserDataAtom, (), _puserDataAtom); @@ -419,11 +429,18 @@ PVA_FF_Mpeg4File::addTrack(int32 mediaType, int32 codecType, uint8 profile, mda = getMediaDataAtomForTrack(0); } + // For track creation, use version 1 of FullBox spec when _oLiveMovieFragmentEnabled is true + uint8 fbVersion = 0; + if (_oLiveMovieFragmentEnabled) + fbVersion = 1; + + if ((uint32) mediaType == MEDIA_TYPE_AUDIO) { // Create default audio track and add it to moov atom PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtom, (MEDIA_TYPE_AUDIO, _pmovieAtom->getMutableMovieHeaderAtom().findNextTrackID(), + fbVersion, _fileAuthoringFlags, codecType, 1, profile, profileComp, level), @@ -481,6 +498,7 @@ PVA_FF_Mpeg4File::addTrack(int32 mediaType, int32 codecType, uint8 profile, // Create default video track and add it to moov atom PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtom, (MEDIA_TYPE_VISUAL, _pmovieAtom->getMutableMovieHeaderAtom().findNextTrackID(), + fbVersion, _fileAuthoringFlags, codecType, 1, profile, profileComp, level), @@ -517,6 +535,7 @@ PVA_FF_Mpeg4File::addTrack(int32 mediaType, int32 codecType, uint8 profile, // Create default video track and add it to moov atom PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtom, (MEDIA_TYPE_TEXT, _pmovieAtom->getMutableMovieHeaderAtom().findNextTrackID(), + fbVersion, _fileAuthoringFlags, codecType, 1, @@ -568,6 +587,23 @@ PVA_FF_Mpeg4File::setTimeScale(uint32 trackID, uint32 rate) return; } +bool +PVA_FF_Mpeg4File::setTrackDuration(uint32 trackID, uint64 duration) +{ + PVA_FF_TrackAtom *mediaTrack = _pmovieAtom->getMediaTrack(trackID); + if (mediaTrack == NULL) + return false; + + // Track duration can only be set for mode PVMP4FF_LIVE_MOVIE_FRAGMENT_MODE + if (_oLiveMovieFragmentEnabled == false) + return false; + + PVA_FF_TrackHeaderAtom *ptkhdr = mediaTrack->getTrackHeaderAtomPtr(); + ptkhdr->setDuration(duration); + + return true; +} + //this will work same as the addsampletotrack but this //will be called only for timed text file format bool PVA_FF_Mpeg4File::addTextSampleToTrack(uint32 trackID, PVMP4FFComposerSampleParam *pSampleParam) @@ -652,6 +688,7 @@ void PVA_FF_Mpeg4File::setMovieFragmentDuration(uint32 duration) { _movieFragmentDuration = duration; + _pmovieAtom->setMovieFragmentDuration(duration); return; } @@ -2453,7 +2490,7 @@ PVA_FF_Mpeg4File::addMediaSampleInterleave(uint32 trackID, PVMP4FFComposerSample _pCurrentMoofAtom = pMoofAtom; // set Movie fragment duration - _pmovieAtom->setMovieFragmentDuration(); + _pmovieAtom->setMovieFragmentDuration(_movieFragmentDuration); // add track fragments for (uint32 kk = 0; kk < _pmediaDataAtomVec->size(); kk++) diff --git a/fileformats/mp4/composer/src/trackatom.cpp b/fileformats/mp4/composer/src/trackatom.cpp index 82c604ce..39eb6843 100644 --- a/fileformats/mp4/composer/src/trackatom.cpp +++ b/fileformats/mp4/composer/src/trackatom.cpp @@ -33,6 +33,7 @@ typedef Oscl_Vector uint8VecType; // Constructor PVA_FF_TrackAtom::PVA_FF_TrackAtom(int32 type, uint32 id, + uint8 version, uint32 fileAuthoringFlags, int32 codecType, uint32 protocol, @@ -68,10 +69,11 @@ PVA_FF_TrackAtom::PVA_FF_TrackAtom(int32 type, _setDecoderSpecificInfoDone = true; } - PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackHeaderAtom, (type, id, (uint8)0, (uint32)0x000001, fileAuthoringFlags), _ptrackHeader); + PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackHeaderAtom, (type, id, version, (uint32)0x000001, fileAuthoringFlags), _ptrackHeader); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MediaAtom, (type, codecType, + version, fileAuthoringFlags, protocol, profile, profileComp, level), @@ -269,13 +271,14 @@ PVA_FF_TrackAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) { int32 rendered = 0; // Keep track of number of bytes rendered - uint32 creationTime = _ptrackHeader->getCreationTime(); - uint32 modTime = _ptrackHeader->getModificationTime(); + uint64 creationTime = _ptrackHeader->getCreationTime(); + uint64 modTime = _ptrackHeader->getModificationTime(); PVA_FF_MediaHeaderAtom *mdhdPtr = _pmediaAtom->getMediaHeaderAtomPtr(); mdhdPtr->setCreationTime(creationTime); mdhdPtr->setModificationTime(modTime); + mdhdPtr->setDuration(getDuration()); recomputeSize(); diff --git a/fileformats/mp4/composer/src/trackheaderatom.cpp b/fileformats/mp4/composer/src/trackheaderatom.cpp index 18783de3..ff5a82a9 100644 --- a/fileformats/mp4/composer/src/trackheaderatom.cpp +++ b/fileformats/mp4/composer/src/trackheaderatom.cpp @@ -26,6 +26,8 @@ #include "trackheaderatom.h" #include "atomutils.h" #include "a_atomdefs.h" +#include "oscl_int64_utils.h" + #define TIMED_TEXT_WIDTH 176 #define TIMED_TEXT_HEIGHT 177 @@ -54,8 +56,12 @@ PVA_FF_TrackHeaderAtom::~PVA_FF_TrackHeaderAtom() void PVA_FF_TrackHeaderAtom::init(int32 type) { - PVA_FF_AtomUtils::setTime(_creationTime); - PVA_FF_AtomUtils::setTime(_modificationTime); + // use a temporary variable to set the current time since the API setTime takes uint32 parameters + uint32 timeSet; + PVA_FF_AtomUtils::setTime(timeSet); + _creationTime = timeSet; + PVA_FF_AtomUtils::setTime(timeSet); + _modificationTime = timeSet; setTimeScale(0); _duration = 0; @@ -148,11 +154,23 @@ void PVA_FF_TrackHeaderAtom::recomputeSize() { int32 size = getDefaultSize(); // From base class - size += 4; // _creationTime; - size += 4; // _modificationTime + + // Fields that vary depending on the version + if (getVersion() == 0) + { + size += 4; //_creationTime + size += 4; //_modificationTime + size += 4; //_duration + } + else // getVersion() == 1 + { + size += 8; //_creationTime + size += 8; //_modificationTime + size += 8; //_duration + } + size += 4; // _trackID; size += 4; // _reserved1 - size += 4; // _duration; size += 60; // rest of reserved words _size = size; @@ -177,13 +195,31 @@ PVA_FF_TrackHeaderAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) } rendered += getDefaultSize(); - if (!PVA_FF_AtomUtils::render32(fp, getCreationTime())) + if (getVersion() == 0) { - return false; + if (!PVA_FF_AtomUtils::render32(fp, + Oscl_Int64_Utils::get_uint64_lower32(getCreationTime()))) + { + return false; + } + + if (!PVA_FF_AtomUtils::render32(fp, + Oscl_Int64_Utils::get_uint64_lower32(getModificationTime()))) + + { + return false; + } } - if (!PVA_FF_AtomUtils::render32(fp, getModificationTime())) + else // getVersion() == 1 { - return false; + if (!PVA_FF_AtomUtils::render64(fp, getCreationTime())) + { + return false; + } + if (!PVA_FF_AtomUtils::render64(fp, getModificationTime())) + { + return false; + } } trackID = getTrackID(); @@ -193,7 +229,16 @@ PVA_FF_TrackHeaderAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) { return false; } - rendered += 12; + + + if (getVersion() == 0) + { + rendered += 12; + } + else + { + rendered += 20; + } if (!PVA_FF_AtomUtils::render32(fp, _reserved1)) { @@ -206,18 +251,32 @@ PVA_FF_TrackHeaderAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp) * last sample as well, which in our case is same as the last but one. */ - uint32 totalDuration = getDuration(); + uint64 totalDuration = getDuration(); - if (!totalDuration) + if (totalDuration == 0) { totalDuration = _currTrackDuration; } - if (!PVA_FF_AtomUtils::render32(fp, totalDuration)) + if (getVersion() == 0) { - return false; + if (!PVA_FF_AtomUtils::render32(fp, + Oscl_Int64_Utils::get_uint64_lower32(totalDuration))) + { + return false; + } + + rendered += 4; + } + else // getVersion() == 1 + { + if (!PVA_FF_AtomUtils::render64(fp, totalDuration)) + { + return false; + } + + rendered += 8; } - rendered += 4; if (!PVA_FF_AtomUtils::render32(fp, _reserved2[0])) {