From 00cf8ff30aabc6db84484255d8daafaef94b81da Mon Sep 17 00:00:00 2001 From: Chema Gonzalez Date: Tue, 2 Jul 2024 16:43:04 -0700 Subject: [PATCH 1/3] isobmff: add C dependency memcpy() is included in Tested: Built in Fedora. --- ISOBMFF/source/BinaryDataStream.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ISOBMFF/source/BinaryDataStream.cpp b/ISOBMFF/source/BinaryDataStream.cpp index 66f6a1e..370ee35 100644 --- a/ISOBMFF/source/BinaryDataStream.cpp +++ b/ISOBMFF/source/BinaryDataStream.cpp @@ -28,6 +28,8 @@ * @author Jean-David Gadina - www.digidna.net */ +#include + #include #include #include From 5bbf4c526bec7b92f6568a649dccebfb3d579c18 Mon Sep 17 00:00:00 2001 From: Chema Gonzalez Date: Tue, 2 Jul 2024 19:23:11 -0700 Subject: [PATCH 2/3] add MDHD box --- ISOBMFF/include/ISOBMFF.hpp | 1 + ISOBMFF/include/ISOBMFF/MDHD.hpp | 91 ++++++++++ ISOBMFF/source/MDHD.cpp | 286 +++++++++++++++++++++++++++++++ ISOBMFF/source/Parser.cpp | 2 + 4 files changed, 380 insertions(+) create mode 100644 ISOBMFF/include/ISOBMFF/MDHD.hpp create mode 100644 ISOBMFF/source/MDHD.cpp diff --git a/ISOBMFF/include/ISOBMFF.hpp b/ISOBMFF/include/ISOBMFF.hpp index 3a0eb05..eefadc2 100644 --- a/ISOBMFF/include/ISOBMFF.hpp +++ b/ISOBMFF/include/ISOBMFF.hpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include diff --git a/ISOBMFF/include/ISOBMFF/MDHD.hpp b/ISOBMFF/include/ISOBMFF/MDHD.hpp new file mode 100644 index 0000000..37010d2 --- /dev/null +++ b/ISOBMFF/include/ISOBMFF/MDHD.hpp @@ -0,0 +1,91 @@ +/******************************************************************************* + * The MIT License (MIT) + * + * Copyright (c) 2017 DigiDNA - www.digidna.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +/*! + * @header MDHD.hpp + * @copyright (c) 2017, DigiDNA - www.digidna.net + * @author Jean-David Gadina - www.digidna.net + */ + +#ifndef ISOBMFF_MDHD_HPP +#define ISOBMFF_MDHD_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace ISOBMFF +{ + class ISOBMFF_EXPORT MDHD: public FullBox, public DisplayableObjectContainer + { + public: + + MDHD(); + MDHD( const MDHD & o ); + MDHD( MDHD && o ) noexcept; + virtual ~MDHD() override; + + MDHD & operator =( MDHD o ); + + void ReadData( Parser & parser, BinaryStream & stream ) override; + void WriteDescription( std::ostream & os, std::size_t indentLevel ) const override; + + virtual std::vector< std::shared_ptr< DisplayableObject > > GetDisplayableObjects() const override; + virtual std::vector< std::pair< std::string, std::string > > GetDisplayableProperties() const override; + + uint64_t GetCreationTime() const; + uint64_t GetModificationTime() const; + uint32_t GetTimescale() const; + uint64_t GetDuration() const; + uint8_t GetPad() const; + uint8_t GetLanguage0() const; + uint8_t GetLanguage1() const; + uint8_t GetLanguage2() const; + uint16_t GetPredefined() const; + + void SetCreationTime( uint64_t value ); + void SetModificationTime( uint64_t value ); + void SetTimescale( uint32_t value ); + void SetDuration( uint64_t value ); + void SetPad( uint8_t value ); + void SetLanguage0( uint8_t value ); + void SetLanguage1( uint8_t value ); + void SetLanguage2( uint8_t value ); + void SetPredefined( uint16_t value ); + + ISOBMFF_EXPORT friend void swap( MDHD & o1, MDHD & o2 ); + + private: + + class IMPL; + + std::unique_ptr< IMPL > impl; + }; +} + +#endif /* ISOBMFF_MDHD_HPP */ diff --git a/ISOBMFF/source/MDHD.cpp b/ISOBMFF/source/MDHD.cpp new file mode 100644 index 0000000..9a75bfe --- /dev/null +++ b/ISOBMFF/source/MDHD.cpp @@ -0,0 +1,286 @@ +/******************************************************************************* + * The MIT License (MIT) + * + * Copyright (c) 2017 DigiDNA - www.digidna.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +/*! + * @file MDHD.cpp + * @copyright (c) 2017, DigiDNA - www.digidna.net + * @author Jean-David Gadina - www.digidna.net + */ + +#include + +namespace ISOBMFF +{ + class MDHD::IMPL + { + public: + + IMPL(); + IMPL( const IMPL & o ); + ~IMPL(); + + uint64_t _creationTime; + uint64_t _modificationTime; + uint32_t _timescale; + uint64_t _duration; + uint8_t _pad; + uint8_t _language0; + uint8_t _language1; + uint8_t _language2; + uint16_t _predefined; + }; + + MDHD::MDHD(): + FullBox( "mdhd" ), + impl( std::make_unique< IMPL >() ) + {} + + MDHD::MDHD( const MDHD & o ): + FullBox( o ), + impl( std::make_unique< IMPL >( *( o.impl ) ) ) + {} + + MDHD::MDHD( MDHD && o ) noexcept: + FullBox( std::move( o ) ), + impl( std::move( o.impl ) ) + { + o.impl = nullptr; + } + + MDHD::~MDHD() + {} + + MDHD & MDHD::operator =( MDHD o ) + { + FullBox::operator=( o ); + swap( *( this ), o ); + + return *( this ); + } + + void swap( MDHD & o1, MDHD & o2 ) + { + using std::swap; + + swap( static_cast< FullBox & >( o1 ), static_cast< FullBox & >( o2 ) ); + swap( o1.impl, o2.impl ); + } + + void MDHD::ReadData( Parser & parser, BinaryStream & stream ) + { + uint64_t u64; + uint32_t u32; + uint16_t u16; + + FullBox::ReadData( parser, stream ); + + if( this->GetVersion() == 1 ) + { + u64 = stream.ReadBigEndianUInt64(); + } + else + { + u64 = stream.ReadBigEndianUInt32(); + } + this->SetCreationTime( u64 ); + + if( this->GetVersion() == 1 ) + { + u64 = stream.ReadBigEndianUInt64(); + } + else + { + u64 = stream.ReadBigEndianUInt32(); + } + this->SetModificationTime( u64 ); + + u32 = stream.ReadBigEndianUInt32(); + this->SetTimescale( u32 ); + + if( this->GetVersion() == 1 ) + { + u64 = stream.ReadBigEndianUInt64(); + } + else + { + u64 = stream.ReadBigEndianUInt32(); + } + this->SetDuration( u64 ); + + u16 = stream.ReadBigEndianUInt16(); + this->SetPad( u16 >> 15 ); + this->SetLanguage0( (u16 >> 10) & 0b11111 ); + this->SetLanguage1( (u16 >> 5) & 0b11111 ); + this->SetLanguage2( (u16 >> 0) & 0b11111 ); + + u16 = stream.ReadBigEndianUInt16(); + this->SetPredefined( u16 ); + } + + void MDHD::WriteDescription( std::ostream & os, std::size_t indentLevel ) const + { + FullBox::WriteDescription( os, indentLevel ); + DisplayableObjectContainer::WriteDescription( os, indentLevel ); + } + + std::vector< std::shared_ptr< DisplayableObject > > MDHD::GetDisplayableObjects() const + { + return std::vector< std::shared_ptr< DisplayableObject > >{}; + } + + std::vector< std::pair< std::string, std::string > > MDHD::GetDisplayableProperties() const + { + auto props( FullBox::GetDisplayableProperties() ); + + props.push_back( { "Creation time", std::to_string( this->GetCreationTime() ) } ); + props.push_back( { "Modification time", std::to_string( this->GetModificationTime() ) } ); + props.push_back( { "Timescale", std::to_string( this->GetTimescale() ) } ); + props.push_back( { "Duration", std::to_string( this->GetDuration() ) } ); + props.push_back( { "Pad", std::to_string( this->GetPad() ) } ); + props.push_back( { "Language0", std::to_string( this->GetLanguage0() ) } ); + props.push_back( { "Language1", std::to_string( this->GetLanguage1() ) } ); + props.push_back( { "Language2", std::to_string( this->GetLanguage2() ) } ); + props.push_back( { "Predefined", std::to_string( this->GetPredefined() ) } ); + + return props; + } + + uint64_t MDHD::GetCreationTime() const + { + return this->impl->_creationTime; + } + + uint64_t MDHD::GetModificationTime() const + { + return this->impl->_modificationTime; + } + + uint32_t MDHD::GetTimescale() const + { + return this->impl->_timescale; + } + + uint64_t MDHD::GetDuration() const + { + return this->impl->_duration; + } + + uint8_t MDHD::GetPad() const + { + return this->impl->_pad; + } + + uint8_t MDHD::GetLanguage0() const + { + return this->impl->_language0; + } + + uint8_t MDHD::GetLanguage1() const + { + return this->impl->_language1; + } + + uint8_t MDHD::GetLanguage2() const + { + return this->impl->_language2; + } + + uint16_t MDHD::GetPredefined() const + { + return this->impl->_predefined; + } + + void MDHD::SetCreationTime( uint64_t value ) + { + this->impl->_creationTime = value; + } + + void MDHD::SetModificationTime( uint64_t value ) + { + this->impl->_modificationTime = value; + } + + void MDHD::SetTimescale( uint32_t value ) + { + this->impl->_timescale = value; + } + + void MDHD::SetDuration( uint64_t value ) + { + this->impl->_duration = value; + } + + void MDHD::SetPad( uint8_t value ) + { + this->impl->_pad = value; + } + + void MDHD::SetLanguage0( uint8_t value ) + { + this->impl->_language0 = value; + } + + void MDHD::SetLanguage1( uint8_t value ) + { + this->impl->_language1 = value; + } + + void MDHD::SetLanguage2( uint8_t value ) + { + this->impl->_language2 = value; + } + + void MDHD::SetPredefined( uint16_t value ) + { + this->impl->_predefined = value; + } + + + MDHD::IMPL::IMPL(): + _creationTime( 0 ), + _modificationTime( 0 ), + _timescale( 0 ), + _duration( 0 ), + _pad( 0 ), + _language0( 0 ), + _language1( 0 ), + _language2( 0 ), + _predefined( 0 ) + {} + + MDHD::IMPL::IMPL( const IMPL & o ): + _creationTime( o._creationTime ), + _modificationTime( o._modificationTime ), + _timescale( o._timescale ), + _duration( o._duration ), + _pad( o._pad ), + _language0( o._language0 ), + _language1( o._language1 ), + _language2( o._language2 ), + _predefined( o._predefined ) + {} + + MDHD::IMPL::~IMPL() + {} +} diff --git a/ISOBMFF/source/Parser.cpp b/ISOBMFF/source/Parser.cpp index 8fdb62f..8111530 100644 --- a/ISOBMFF/source/Parser.cpp +++ b/ISOBMFF/source/Parser.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -346,6 +347,7 @@ namespace ISOBMFF this->RegisterBox( "tkhd", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< TKHD >(); } ); this->RegisterBox( "meta", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< META >(); } ); this->RegisterBox( "hdlr", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< HDLR >(); } ); + this->RegisterBox( "mdhd", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< MDHD >(); } ); this->RegisterBox( "pitm", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< PITM >(); } ); this->RegisterBox( "iinf", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< IINF >(); } ); this->RegisterBox( "dref", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< DREF >(); } ); From 8df12c3f3a3b0cd99b93d27d526e65191ed52326 Mon Sep 17 00:00:00 2001 From: Chema Gonzalez Date: Tue, 2 Jul 2024 20:53:00 -0700 Subject: [PATCH 3/3] add STTS box --- ISOBMFF/include/ISOBMFF.hpp | 1 + ISOBMFF/include/ISOBMFF/STTS.hpp | 70 ++++++++++++++++ ISOBMFF/source/Parser.cpp | 2 + ISOBMFF/source/STTS.cpp | 135 +++++++++++++++++++++++++++++++ 4 files changed, 208 insertions(+) create mode 100644 ISOBMFF/include/ISOBMFF/STTS.hpp create mode 100644 ISOBMFF/source/STTS.cpp diff --git a/ISOBMFF/include/ISOBMFF.hpp b/ISOBMFF/include/ISOBMFF.hpp index eefadc2..17c0607 100644 --- a/ISOBMFF/include/ISOBMFF.hpp +++ b/ISOBMFF/include/ISOBMFF.hpp @@ -72,6 +72,7 @@ #include #include #include +#include #include #include diff --git a/ISOBMFF/include/ISOBMFF/STTS.hpp b/ISOBMFF/include/ISOBMFF/STTS.hpp new file mode 100644 index 0000000..6309832 --- /dev/null +++ b/ISOBMFF/include/ISOBMFF/STTS.hpp @@ -0,0 +1,70 @@ +/******************************************************************************* + * The MIT License (MIT) + * + * Copyright (c) 2017 DigiDNA - www.digidna.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +/*! + * @header STTS.hpp + * @copyright (c) 2017, DigiDNA - www.digidna.net + * @author Jean-David Gadina - www.digidna.net + */ + +#ifndef ISOBMFF_STTS_HPP +#define ISOBMFF_STTS_HPP + +#include +#include +#include +#include +#include + +namespace ISOBMFF +{ + class ISOBMFF_EXPORT STTS: public FullBox + { + public: + + STTS(); + STTS( const STTS & o ); + STTS( STTS && o ) noexcept; + virtual ~STTS() override; + + STTS & operator =( STTS o ); + + void ReadData( Parser & parser, BinaryStream & stream ) override; + std::vector< std::pair< std::string, std::string > > GetDisplayableProperties() const override; + + uint32_t GetEntryCount() const; + uint32_t GetSampleCount(unsigned int index) const; + uint32_t GetSampleOffset(unsigned int index) const; + + ISOBMFF_EXPORT friend void swap( STTS & o1, STTS & o2 ); + + private: + + class IMPL; + + std::unique_ptr< IMPL > impl; + }; +} + +#endif /* ISOBMFF_STTS_HPP */ diff --git a/ISOBMFF/source/Parser.cpp b/ISOBMFF/source/Parser.cpp index 8111530..f1efce9 100644 --- a/ISOBMFF/source/Parser.cpp +++ b/ISOBMFF/source/Parser.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -367,6 +368,7 @@ namespace ISOBMFF this->RegisterBox( "pixi", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< PIXI >(); } ); this->RegisterBox( "ipco", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< IPCO >(); } ); this->RegisterBox( "stsd", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< STSD >(); } ); + this->RegisterBox( "stts", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< STTS >(); } ); this->RegisterBox( "frma", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< FRMA >(); } ); this->RegisterBox( "schm", [ = ]() -> std::shared_ptr< Box > { return std::make_shared< SCHM >(); } ); } diff --git a/ISOBMFF/source/STTS.cpp b/ISOBMFF/source/STTS.cpp new file mode 100644 index 0000000..805514b --- /dev/null +++ b/ISOBMFF/source/STTS.cpp @@ -0,0 +1,135 @@ +/******************************************************************************* + * The MIT License (MIT) + * + * Copyright (c) 2017 DigiDNA - www.digidna.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +/*! + * @file STTS.cpp + * @copyright (c) 2017, DigiDNA - www.digidna.net + * @author Jean-David Gadina - www.digidna.net + */ + +#include +#include +#include +#include + +namespace ISOBMFF +{ + class STTS::IMPL + { + public: + + IMPL(); + IMPL( const IMPL & o ); + ~IMPL(); + + std::vector _sample_count; + std::vector _sample_offset; + }; + + STTS::STTS(): + FullBox( "stts" ), + impl( std::make_unique< IMPL >() ) + {} + + STTS::STTS( const STTS & o ): + FullBox( o ), + impl( std::make_unique< IMPL >( *( o.impl ) ) ) + {} + + STTS::STTS( STTS && o ) noexcept: + FullBox( std::move( o ) ), + impl( std::move( o.impl ) ) + { + o.impl = nullptr; + } + + STTS::~STTS() + {} + + STTS & STTS::operator =( STTS o ) + { + FullBox::operator=( o ); + swap( *( this ), o ); + + return *( this ); + } + + void swap( STTS & o1, STTS & o2 ) + { + using std::swap; + + swap( static_cast< FullBox & >( o1 ), static_cast< FullBox & >( o2 ) ); + swap( o1.impl, o2.impl ); + } + + void STTS::ReadData( Parser & parser, BinaryStream & stream ) + { + FullBox::ReadData( parser, stream ); + + uint32_t entry_count = stream.ReadBigEndianUInt32(); + for (uint32_t i = 0; i < entry_count; i++) { + this->impl->_sample_count.push_back(stream.ReadBigEndianUInt32()); + this->impl->_sample_offset.push_back(stream.ReadBigEndianUInt32()); + } + } + + std::vector< std::pair< std::string, std::string > > STTS::GetDisplayableProperties() const + { + auto props( FullBox::GetDisplayableProperties() ); + for (unsigned int index = 0; index < this->GetEntryCount(); index++) { + props.push_back( { "Sample Count", std::to_string( this->GetSampleCount(index) ) } ); + props.push_back( { "Sample Offset", std::to_string( this->GetSampleOffset(index) ) } ); + } + + return props; + } + + uint32_t STTS::GetEntryCount() const + { + return this->impl->_sample_count.size(); + } + + uint32_t STTS::GetSampleCount(unsigned int index) const + { + return this->impl->_sample_count[index]; + } + + uint32_t STTS::GetSampleOffset(unsigned int index) const + { + return this->impl->_sample_offset[index]; + } + + STTS::IMPL::IMPL() + { + } + + STTS::IMPL::IMPL( const IMPL & o ) + { + this->_sample_count = o._sample_count; + this->_sample_offset = o._sample_offset; + } + + STTS::IMPL::~IMPL() + {} +}