From 0b270e680bc483bc57f48d7d373358614f1fa08d Mon Sep 17 00:00:00 2001 From: "d.cheng" Date: Mon, 21 Jan 2013 14:39:04 +0000 Subject: [PATCH] I think I merged all of my changes in correctly here ... --- include/mp4v2/file.h | 1 + include/mp4v2/sample.h | 8 +++++ include/mp4v2/track.h | 8 +++++ include/mp4v2/track_prop.h | 10 ++++++ libplatform/io/File.cpp | 18 +++++++++- libplatform/io/File.h | 5 +++ libplatform/io/File_posix.cpp | 11 ++++++ src/atom_mp4v.cpp | 51 +++++++++++++++++++++++++++ src/atoms.h | 10 ++++++ src/mp4.cpp | 66 +++++++++++++++++++++++++++++++++++ src/mp4atom.cpp | 5 +++ src/mp4file.cpp | 44 +++++++++++++++++++++++ src/mp4file.h | 10 ++++++ src/mp4track.h | 3 +- 14 files changed, 248 insertions(+), 2 deletions(-) diff --git a/include/mp4v2/file.h b/include/mp4v2/file.h index fc0c5ef..32760de 100644 --- a/include/mp4v2/file.h +++ b/include/mp4v2/file.h @@ -40,6 +40,7 @@ typedef struct MP4FileProvider_s int ( *read )( void* handle, void* buffer, int64_t size, int64_t* nin, int64_t maxChunkSize ); int ( *write )( void* handle, const void* buffer, int64_t size, int64_t* nout, int64_t maxChunkSize ); int ( *close )( void* handle ); + int64_t ( *size)( void* handle ); } MP4FileProvider; /** Close an mp4 file. diff --git a/include/mp4v2/sample.h b/include/mp4v2/sample.h index ba35a57..69bbee2 100644 --- a/include/mp4v2/sample.h +++ b/include/mp4v2/sample.h @@ -552,6 +552,14 @@ int8_t MP4GetSampleSync( MP4TrackId trackId, MP4SampleId sampleId ); + +/* */ +MP4V2_EXPORT +uint64_t MP4GetSampleFileOffset( + MP4FileHandle hFile, + MP4TrackId trackId, + MP4SampleId sampleId ); + /* @} ***********************************************************************/ #endif /* MP4V2_SAMPLE_H */ diff --git a/include/mp4v2/track.h b/include/mp4v2/track.h index 90eb7bc..682792e 100644 --- a/include/mp4v2/track.h +++ b/include/mp4v2/track.h @@ -246,6 +246,14 @@ MP4TrackId MP4AddVideoTrack( uint16_t height, uint8_t videoType DEFAULT(MP4_MPEG4_VIDEO_TYPE) ); +MP4V2_EXPORT +MP4TrackId MP4AddTSC2VideoTrack( + MP4FileHandle hFile, + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height ); + MP4V2_EXPORT MP4TrackId MP4AddH264VideoTrack( MP4FileHandle hFile, diff --git a/include/mp4v2/track_prop.h b/include/mp4v2/track_prop.h index 37d7643..bbd5e7d 100644 --- a/include/mp4v2/track_prop.h +++ b/include/mp4v2/track_prop.h @@ -16,6 +16,16 @@ bool MP4HaveTrackAtom( MP4TrackId trackId, const char* atomname ); + +MP4V2_EXPORT +bool MP4GetTrackAtomData ( + MP4FileHandle hFile, + MP4TrackId trackId, + const char *atomName, + uint8_t ** outAtomData, + uint64_t * outDataSize); + + /** Get the track type. * * MP4GetTrackType gets the type of the track with the specified track id. diff --git a/libplatform/io/File.cpp b/libplatform/io/File.cpp index 893f98c..f041c37 100644 --- a/libplatform/io/File.cpp +++ b/libplatform/io/File.cpp @@ -63,7 +63,8 @@ File::open( std::string name_, Mode mode_ ) if( _provider.open( _name, _mode )) return true; - FileSystem::getFileSize( _name, _size ); + _size = _provider.getSize(); + //FileSystem::getFileSize( _name, _size ); _isOpen = true; return false; @@ -129,6 +130,13 @@ File::close() return false; } +int64_t File::getSize() +{ + int64_t retSize = 0; + FileSystem::getFileSize( _name, retSize ); + return retSize; +} + /////////////////////////////////////////////////////////////////////////////// CustomFileProvider::CustomFileProvider( const MP4FileProvider& provider ) @@ -140,6 +148,7 @@ CustomFileProvider::CustomFileProvider( const MP4FileProvider& provider ) bool CustomFileProvider::open( std::string name, Mode mode ) { + fprintf(stderr, "CustomFileProvider::open()\n"); MP4FileMode fm; switch( mode ) { case MODE_READ: fm = FILEMODE_READ; break; @@ -180,6 +189,13 @@ CustomFileProvider::close() return _call.close( _handle ); } +int64_t CustomFileProvider::getSize() +{ + fprintf(stderr, "CustomFileProvider::getSize()\n"); + assert( _call.size ); + return _call.size( _handle ); +} + /////////////////////////////////////////////////////////////////////////////// }}} // namespace mp4v2::platform::io diff --git a/libplatform/io/File.h b/libplatform/io/File.h index 67bb2b6..b1d62b5 100644 --- a/libplatform/io/File.h +++ b/libplatform/io/File.h @@ -31,6 +31,7 @@ class MP4V2_EXPORT FileProvider virtual bool write( const void* buffer, Size size, Size& nout, Size maxChunkSize ) = 0; virtual bool close() = 0; + virtual int64_t getSize() = 0; protected: FileProvider() { } }; @@ -163,6 +164,9 @@ class MP4V2_EXPORT File : public FileProvider bool write( const void* buffer, Size size, Size& nout, Size maxChunkSize = 0 ); + int64_t getSize(); + + private: std::string _name; bool _isOpen; @@ -196,6 +200,7 @@ class CustomFileProvider : public FileProvider bool write( const void* buffer, Size size, Size& nout, Size maxChunkSize ); bool close(); + int64_t getSize(); private: MP4FileProvider _call; void* _handle; diff --git a/libplatform/io/File_posix.cpp b/libplatform/io/File_posix.cpp index b6fb214..42ae64f 100644 --- a/libplatform/io/File_posix.cpp +++ b/libplatform/io/File_posix.cpp @@ -15,10 +15,13 @@ class StandardFileProvider : public FileProvider bool write( const void* buffer, Size size, Size& nout, Size maxChunkSize ); bool close(); + int64_t getSize(); + private: bool _seekg; bool _seekp; std::fstream _fstream; + std::string _name; }; /////////////////////////////////////////////////////////////////////////////// @@ -56,6 +59,7 @@ StandardFileProvider::open( std::string name, Mode mode ) } _fstream.open( name.c_str(), om ); + _name = name; return _fstream.fail(); } @@ -96,6 +100,13 @@ StandardFileProvider::close() return _fstream.fail(); } +int64_t StandardFileProvider::getSize() +{ + int64_t retSize = 0; + FileSystem::getFileSize( _name, retSize ); + return retSize; +} + /////////////////////////////////////////////////////////////////////////////// FileProvider& diff --git a/src/atom_mp4v.cpp b/src/atom_mp4v.cpp index 9cf6444..febfa0a 100644 --- a/src/atom_mp4v.cpp +++ b/src/atom_mp4v.cpp @@ -85,6 +85,57 @@ void MP4Mp4vAtom::Generate() m_pProperties[7]->SetReadOnly(true); } +/////////////////////////////////////////////////////////////////////////////// +MP4Tsc2Atom::MP4Tsc2Atom(MP4File &file) + : MP4Atom(file, "tsc2") +{ + AddReserved(*this, "reserved1", 6); + AddProperty(new MP4Integer16Property(*this, "dataReferenceIndex")); + AddReserved(*this, "reserved2", 16); + AddProperty(new MP4Integer16Property(*this, "width")); + AddProperty(new MP4Integer16Property(*this, "height")); + AddReserved(*this, "reserved3", 14); + + MP4StringProperty* pProp = new MP4StringProperty(*this, "compressorName"); + pProp->SetFixedLength(32); + pProp->SetCountedFormat(true); +// pProp->SetValue("TSC2 Codec"); + AddProperty(pProp); + AddReserved(*this, "reserved4", 4); /* 7 */ + + ExpectChildAtom("colr", Optional, OnlyOne); + ExpectChildAtom("esds", Required, OnlyOne); + ExpectChildAtom("pasp", Optional, OnlyOne); +} + +void MP4Tsc2Atom::Generate() +{ + MP4Atom::Generate(); + + ((MP4Integer16Property*)m_pProperties[1])->SetValue(1); + + // property reserved3 has non-zero fixed values + static uint8_t reserved3[14] = { + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, + }; + m_pProperties[5]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[5])-> + SetValue(reserved3, sizeof(reserved3)); + m_pProperties[5]->SetReadOnly(true); + + // property reserved4 has non-zero fixed values + static uint8_t reserved4[4] = { + 0x00, 0x18, 0xFF, 0xFF, + }; + m_pProperties[7]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[7])-> + SetValue(reserved4, sizeof(reserved4)); + m_pProperties[7]->SetReadOnly(true); +} + /////////////////////////////////////////////////////////////////////////////// } diff --git a/src/atoms.h b/src/atoms.h index 382706f..49e30b8 100644 --- a/src/atoms.h +++ b/src/atoms.h @@ -271,6 +271,16 @@ class MP4Mp4vAtom : public MP4Atom { MP4Mp4vAtom &operator= ( const MP4Mp4vAtom &src ); }; + class MP4Tsc2Atom : public MP4Atom { + public: + MP4Tsc2Atom(MP4File &file); + void Generate(); + private: + MP4Tsc2Atom(); + MP4Tsc2Atom( const MP4Tsc2Atom &src ); + MP4Tsc2Atom &operator= ( const MP4Tsc2Atom &src ); + }; + class MP4S263Atom : public MP4Atom { public: diff --git a/src/mp4.cpp b/src/mp4.cpp index d69b87e..a90c16b 100644 --- a/src/mp4.cpp +++ b/src/mp4.cpp @@ -1108,6 +1108,34 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file return MP4_INVALID_TRACK_ID; } + MP4TrackId MP4AddTSC2VideoTrack( + MP4FileHandle hFile, + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height) + { + if (MP4_IS_VALID_FILE_HANDLE(hFile)) { + try { + MP4File *pFile = (MP4File *)hFile; + + return pFile->AddTSC2VideoTrack(timeScale, + sampleDuration, + width, + height); + } + catch( Exception* x ) { + mp4v2::impl::log.errorf(*x); + delete x; + } + catch( ... ) { + mp4v2::impl::log.errorf( "%s: failed", __FUNCTION__ ); + } + } + return MP4_INVALID_TRACK_ID; + } + + MP4TrackId MP4AddEncVideoTrack(MP4FileHandle hFile, uint32_t timeScale, MP4Duration sampleDuration, @@ -2721,6 +2749,22 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file return false; } + bool MP4GetTrackAtomData (MP4FileHandle hFile, MP4TrackId trackId, const char *atomName, uint8_t ** outAtomData, uint64_t * outDataSize) + { + if (MP4_IS_VALID_FILE_HANDLE(hFile)) { + try { + return ((MP4File *)hFile)->GetTrackAtomData(trackId, atomName, outAtomData, outDataSize); + } catch( Exception* x ) { + mp4v2::impl::log.errorf(*x); + delete x; + } + catch( ... ) { + mp4v2::impl::log.errorf( "%s: failed", __FUNCTION__ ); + } + } + return false; + } + bool MP4GetTrackIntegerProperty ( MP4FileHandle hFile, MP4TrackId trackId, const char* propName, @@ -3138,6 +3182,28 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file return 0; } + uint64_t MP4GetSampleFileOffset( + MP4FileHandle hFile, + MP4TrackId trackId, + MP4SampleId sampleId ) + { + if (MP4_IS_VALID_FILE_HANDLE(hFile)) { + try { + return ((MP4File*)hFile)->GetSampleFileOffset( + trackId, sampleId); + } + catch( Exception* x ) { + mp4v2::impl::log.errorf(*x); + delete x; + } + catch( ... ) { + mp4v2::impl::log.errorf( "%s: failed", __FUNCTION__ ); + } + } + return 0; + } + + uint32_t MP4GetTrackMaxSampleSize( MP4FileHandle hFile, MP4TrackId trackId) diff --git a/src/mp4atom.cpp b/src/mp4atom.cpp index 520cbc8..5644a7e 100644 --- a/src/mp4atom.cpp +++ b/src/mp4atom.cpp @@ -979,6 +979,11 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type ) return new MP4TfhdAtom(file); if( ATOMID(type) == ATOMID("trun") ) return new MP4TrunAtom(file); + + if( ATOMID(type) == ATOMID("tsc2") ) + return new MP4Tsc2Atom(file); + + if( ATOMID(type) == ATOMID("twos") ) return new MP4SoundAtom( file, type ); break; diff --git a/src/mp4file.cpp b/src/mp4file.cpp index 25e241f..2ed0719 100644 --- a/src/mp4file.cpp +++ b/src/mp4file.cpp @@ -1720,6 +1720,28 @@ MP4TrackId MP4File::AddMP4VideoTrack( return trackId; } +MP4TrackId MP4File::AddTSC2VideoTrack( + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height) +{ + MP4TrackId trackId = AddVideoTrackDefault(timeScale, + sampleDuration, + width, + height, + "tsc2"); + + SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.tsc2.width", width); + SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.tsc2.height", height); + SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.tsc2.esds.ESID", 0 ); + + uint8_t videoType = MP4_PRIVATE_VIDEO_TYPE; + SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.tsc2.esds.decConfigDescr.objectTypeId", videoType); + SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.tsc2.esds.decConfigDescr.streamType", MP4VisualStreamType); + return trackId; +} + // ismacrypted MP4TrackId MP4File::AddEncVideoTrack(uint32_t timeScale, MP4Duration sampleDuration, @@ -2960,6 +2982,11 @@ uint32_t MP4File::GetSampleSize(MP4TrackId trackId, MP4SampleId sampleId) return m_pTracks[FindTrackIndex(trackId)]->GetSampleSize(sampleId); } +uint64_t MP4File::GetSampleFileOffset(MP4TrackId trackId, MP4SampleId sampleId) +{ + return m_pTracks[FindTrackIndex(trackId)]->GetSampleFileOffset(sampleId); +} + uint32_t MP4File::GetTrackMaxSampleSize(MP4TrackId trackId) { return m_pTracks[FindTrackIndex(trackId)]->GetMaxSampleSize(); @@ -3106,6 +3133,23 @@ MP4Atom *MP4File::FindTrackAtom (MP4TrackId trackId, const char *name) return FindAtom(MakeTrackName(trackId, name)); } +bool MP4File::GetTrackAtomData(MP4TrackId trackId, const char *name, uint8_t ** outAtomData, uint64_t * outDataSize) +{ + MP4Atom * pAtom = FindTrackAtom(trackId, name); + if ( pAtom == NULL ) + return false; + + // Need to offset past the header (4 bytes for size and 4 bytes for atom type) + SetPosition(pAtom->GetStart() + 4 + 4); + + uint64_t atomSize = pAtom->GetSize(); + uint8_t * data = (uint8_t *)malloc(atomSize); + ReadBytes( data, atomSize ); + *outAtomData = data; + *outDataSize = atomSize; + return true; +} + uint64_t MP4File::GetTrackIntegerProperty(MP4TrackId trackId, const char* name) { return GetIntegerProperty(MakeTrackName(trackId, name)); diff --git a/src/mp4file.h b/src/mp4file.h index 813f90f..f072b07 100644 --- a/src/mp4file.h +++ b/src/mp4file.h @@ -149,6 +149,9 @@ class MP4File /* track properties */ MP4Atom *FindTrackAtom(MP4TrackId trackId, const char *name); + + bool GetTrackAtomData(MP4TrackId trackId, const char *name, uint8_t ** outAtomData, uint64_t * outDataSize); + uint64_t GetTrackIntegerProperty( MP4TrackId trackId, const char* name); float GetTrackFloatProperty( @@ -177,6 +180,7 @@ class MP4File /* sample operations */ uint32_t GetSampleSize(MP4TrackId trackId, MP4SampleId sampleId); + uint64_t GetSampleFileOffset(MP4TrackId trackId, MP4SampleId sampleId); uint32_t GetTrackMaxSampleSize(MP4TrackId trackId); @@ -305,6 +309,12 @@ class MP4File uint16_t height, uint8_t videoType); + MP4TrackId AddTSC2VideoTrack( + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height); + MP4TrackId AddEncVideoTrack( // ismacryp uint32_t timeScale, MP4Duration sampleDuration, diff --git a/src/mp4track.h b/src/mp4track.h index 2a649f2..1317fb0 100644 --- a/src/mp4track.h +++ b/src/mp4track.h @@ -163,11 +163,12 @@ class MP4Track MP4Duration GetDurationPerChunk(); void SetDurationPerChunk( MP4Duration ); + uint64_t GetSampleFileOffset(MP4SampleId sampleId); + protected: bool InitEditListProperties(); File* GetSampleFile( MP4SampleId sampleId ); - uint64_t GetSampleFileOffset(MP4SampleId sampleId); uint32_t GetSampleStscIndex(MP4SampleId sampleId); uint32_t GetChunkStscIndex(MP4ChunkId chunkId); uint32_t GetChunkSize(MP4ChunkId chunkId);