OSDN Git Service

RIO-7563: Adding support for authoring moof clips for live sessions in mo4 composer...
authorPacketVideo CM <engbuild@pv.com>
Wed, 21 Oct 2009 16:46:39 +0000 (09:46 -0700)
committerPacketVideo CM <engbuild@pv.com>
Wed, 21 Oct 2009 16:46:39 +0000 (09:46 -0700)
19 files changed:
engines/2way/src/pv_2way_sdkinfo.h
engines/author/src/pv_author_sdkinfo.h
engines/player/src/pv_player_sdkinfo.h
fileformats/mp4/composer/include/a_atomdefs.h
fileformats/mp4/composer/include/a_impeg4file.h
fileformats/mp4/composer/include/mediaatom.h
fileformats/mp4/composer/include/mediaheaderatom.h
fileformats/mp4/composer/include/movieatom.h
fileformats/mp4/composer/include/movieheaderatom.h
fileformats/mp4/composer/include/mpeg4file.h
fileformats/mp4/composer/include/trackatom.h
fileformats/mp4/composer/include/trackheaderatom.h
fileformats/mp4/composer/src/mediaatom.cpp
fileformats/mp4/composer/src/mediaheaderatom.cpp
fileformats/mp4/composer/src/movieatom.cpp
fileformats/mp4/composer/src/movieheaderatom.cpp
fileformats/mp4/composer/src/mpeg4file.cpp
fileformats/mp4/composer/src/trackatom.cpp
fileformats/mp4/composer/src/trackheaderatom.cpp

index e90e47a..e899a0d 100644 (file)
@@ -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
index fba8a54..1c9687b 100644 (file)
@@ -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
index fea6c03..00faa87 100644 (file)
@@ -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
index dc0385f..a8e11fe 100644 (file)
@@ -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
index c29cb0c..aeba40b 100644 (file)
@@ -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;
index d73729f..ed11ae3 100644 (file)
@@ -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,
index 5a51c75..1970dac 100644 (file)
@@ -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.
 
index 20a0b41..8a50fa3 100644 (file)
@@ -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;
 };
 
 
index 5a2c2c4..da24cca 100644 (file)
@@ -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)
 
index df5100a..25f4a0b 100644 (file)
@@ -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
 
 
index fa75ac8..1b551aa 100644 (file)
@@ -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();
         }
index b1c2fb9..c5c3d14 100644 (file)
@@ -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 };
index ceda6f4..b235428 100644 (file)
@@ -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);
 
index 0250642..10e1a6d 100644 (file)
 #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()))
     {
index bb88409..185e83d 100644 (file)
@@ -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());
-
+    }
 }
 
 
index f4853be..0b52b2d 100644 (file)
@@ -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))
index eb80c57..d93a4c3 100644 (file)
@@ -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++)
index 82c604c..39eb684 100644 (file)
@@ -33,6 +33,7 @@ typedef Oscl_Vector<uint8, OsclMemAllocator> 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();
 
index 18783de..ff5a82a 100644 (file)
@@ -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]))
     {