├── .clang-format ├── .github └── workflows │ ├── build.yml │ └── lint.yml ├── .gitignore ├── CHANGES.md ├── CMakeLists.txt ├── LICENSE ├── NOTICE.md ├── README.md ├── THANKS ├── cmake ├── CPM.cmake ├── REAME.md ├── env.cmake └── tools.cmake ├── example ├── mp4-muxer.cpp └── resource │ ├── resource.cpp │ └── resource.hpp ├── format.bash ├── include └── shiguredo │ └── mp4 │ ├── bitio │ ├── bitio.hpp │ ├── reader.hpp │ └── writer.hpp │ ├── box.hpp │ ├── box │ ├── av1c.hpp │ ├── avc.hpp │ ├── boxes.hpp │ ├── btrt.hpp │ ├── co64.hpp │ ├── colr.hpp │ ├── ctts.hpp │ ├── dOps.hpp │ ├── data.hpp │ ├── dinf.hpp │ ├── dref.hpp │ ├── edts.hpp │ ├── elst.hpp │ ├── emsg.hpp │ ├── esds.hpp │ ├── fiel.hpp │ ├── free.hpp │ ├── ftyp.hpp │ ├── hdlr.hpp │ ├── ilst.hpp │ ├── iods.hpp │ ├── mdat.hpp │ ├── mdhd.hpp │ ├── mdia.hpp │ ├── mehd.hpp │ ├── meta.hpp │ ├── mfhd.hpp │ ├── mfra.hpp │ ├── mfro.hpp │ ├── minf.hpp │ ├── moof.hpp │ ├── moov.hpp │ ├── mvex.hpp │ ├── mvhd.hpp │ ├── pixel_aspect_ratio.hpp │ ├── pssh.hpp │ ├── sample_entry.hpp │ ├── sbgp.hpp │ ├── schi.hpp │ ├── sdtp.hpp │ ├── sgpd.hpp │ ├── sidx.hpp │ ├── sinf.hpp │ ├── skip.hpp │ ├── smhd.hpp │ ├── stbl.hpp │ ├── stco.hpp │ ├── stsc.hpp │ ├── stsd.hpp │ ├── stss.hpp │ ├── stsz.hpp │ ├── stts.hpp │ ├── styp.hpp │ ├── tfdt.hpp │ ├── tfhd.hpp │ ├── tfra.hpp │ ├── tkhd.hpp │ ├── traf.hpp │ ├── trak.hpp │ ├── trex.hpp │ ├── trun.hpp │ ├── udta.hpp │ ├── unsupported.hpp │ ├── url.hpp │ ├── urn.hpp │ ├── vmhd.hpp │ ├── vpc.hpp │ └── wave.hpp │ ├── box_header.hpp │ ├── box_info.hpp │ ├── box_map.hpp │ ├── box_type.hpp │ ├── box_types.hpp │ ├── brand.hpp │ ├── constants.hpp │ ├── endian │ └── endian.hpp │ ├── grouping_type.hpp │ ├── reader │ └── reader.hpp │ ├── stream │ └── stream.hpp │ ├── time │ └── time.hpp │ ├── track │ ├── aac.hpp │ ├── av1.hpp │ ├── h264.hpp │ ├── mp3.hpp │ ├── opus.hpp │ ├── soun.hpp │ ├── track.hpp │ ├── vide.hpp │ └── vpx.hpp │ ├── version.hpp │ └── writer │ ├── faststart_writer.hpp │ ├── simple_writer.hpp │ └── writer.hpp ├── lint.bash ├── src ├── bitio │ ├── bitio.cpp │ ├── reader.cpp │ └── writer.cpp ├── box.cpp ├── box │ ├── av1c.cpp │ ├── avc.cpp │ ├── btrt.cpp │ ├── co64.cpp │ ├── colr.cpp │ ├── ctts.cpp │ ├── dOps.cpp │ ├── data.cpp │ ├── dinf.cpp │ ├── dref.cpp │ ├── edts.cpp │ ├── elst.cpp │ ├── emsg.cpp │ ├── esds.cpp │ ├── fiel.cpp │ ├── free.cpp │ ├── ftyp.cpp │ ├── hdlr.cpp │ ├── ilst.cpp │ ├── iods.cpp │ ├── mdat.cpp │ ├── mdhd.cpp │ ├── mdia.cpp │ ├── mehd.cpp │ ├── meta.cpp │ ├── mfhd.cpp │ ├── mfra.cpp │ ├── mfro.cpp │ ├── minf.cpp │ ├── moof.cpp │ ├── moov.cpp │ ├── mvex.cpp │ ├── mvhd.cpp │ ├── pixel_aspect_ratio.cpp │ ├── pssh.cpp │ ├── sample_entry.cpp │ ├── sbgp.cpp │ ├── schi.cpp │ ├── sdtp.cpp │ ├── sgpd.cpp │ ├── sidx.cpp │ ├── sinf.cpp │ ├── skip.cpp │ ├── smhd.cpp │ ├── stbl.cpp │ ├── stco.cpp │ ├── stsc.cpp │ ├── stsd.cpp │ ├── stss.cpp │ ├── stsz.cpp │ ├── stts.cpp │ ├── styp.cpp │ ├── tfdt.cpp │ ├── tfhd.cpp │ ├── tfra.cpp │ ├── tkhd.cpp │ ├── traf.cpp │ ├── trak.cpp │ ├── trex.cpp │ ├── trun.cpp │ ├── udta.cpp │ ├── unsupported.cpp │ ├── url.cpp │ ├── urn.cpp │ ├── vmhd.cpp │ ├── vpc.cpp │ └── wave.cpp ├── box_header.cpp ├── box_info.cpp ├── box_map.cpp ├── box_type.cpp ├── box_types.cpp ├── cli │ └── mp4-tool.cpp ├── endian │ └── endian.cpp ├── reader │ └── reader.cpp ├── stream │ └── stream.cpp ├── time │ └── time.cpp ├── track │ ├── aac.cpp │ ├── av1.cpp │ ├── h264.cpp │ ├── mp3.cpp │ ├── opus.cpp │ ├── soun.cpp │ ├── track.cpp │ ├── vide.cpp │ └── vpx.cpp ├── version.cpp └── writer │ ├── faststart_writer.cpp │ ├── simple_writer.cpp │ └── writer.cpp └── test ├── CMakeLists.txt ├── bitio ├── CMakeLists.txt ├── bitio.cpp ├── main.cpp ├── reader.cpp └── writer.cpp ├── box_header.cpp ├── box_info.cpp ├── box_type.cpp ├── box_types.cpp ├── endian ├── CMakeLists.txt ├── endian.cpp └── main.cpp ├── integration ├── Makefile ├── README.md ├── input │ └── check ├── output │ ├── Big_Buck_Bunny_360_10s_1MB.mp4.dump │ ├── check │ └── sample-5s.mp4.dump └── resources │ ├── NOTICE │ ├── aac.csv │ ├── av1.csv │ ├── h264.csv │ ├── mp3.csv │ ├── opus.csv │ ├── vp8.csv │ └── vp9.csv ├── main.cpp ├── time ├── CMakeLists.txt ├── main.cpp └── time.cpp ├── track ├── CMakeLists.txt ├── h264.cpp ├── main.cpp └── track.cpp └── version.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Chromium 4 | ReflowComments: false 5 | ColumnLimit: 120 6 | --- 7 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: build-workflow 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | - develop 9 | paths-ignore: 10 | - 'doc/**' 11 | - '**.md' 12 | - 'THANKS' 13 | - 'LICENSE' 14 | - 'NOTICE' 15 | 16 | jobs: 17 | lint: 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | os: 22 | - ubuntu-20.04_x86_64 23 | name: Lint cpp-mp4 for ${{ matrix.os }} 24 | runs-on: ubuntu-20.04 25 | steps: 26 | - name: Install packages 27 | shell: bash 28 | run: | 29 | go install github.com/client9/misspell/cmd/misspell@latest 30 | sudo apt update 31 | sudo apt install -yq shellcheck 32 | sudo rm -rf /var/lib/apt/lists/* 33 | pip3 install --user cpplint 34 | env: 35 | DEBIAN_FRONTEND: noninteractive 36 | - uses: actions/checkout@v4 37 | - name: Lint cpp-mp4 38 | run: PATH=$PATH:~/.local/bin:~/go/bin ./lint.bash 39 | timeout-minutes: 120 40 | - name: Slack Notification 41 | if: failure() 42 | uses: rtCamp/action-slack-notify@v2 43 | env: 44 | SLACK_CHANNEL: hisui 45 | SLACK_COLOR: danger 46 | SLACK_TITLE: Failure lint 47 | SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # 変更履歴 2 | 3 | - CHANGE 4 | - 下位互換のない変更 5 | - UPDATE 6 | - 下位互換がある変更 7 | - ADD 8 | - 下位互換がある追加 9 | - FIX 10 | - バグ修正 11 | 12 | 13 | ## develop 14 | 15 | - [UPDATE] Github Actions の actions/cache, actions/checkout をアップデート 16 | - Node.js 16 の Deprecated に伴うアップデート 17 | - actions/cache@v3 から actions/cache@v4 にアップデート 18 | - @miosakuma @torikizi 19 | 20 | ## 2023.2.1 21 | 22 | - [FIX] Version 上げ忘れを修正 23 | - @haruyama 24 | 25 | ## 2023.2.0 26 | 27 | - [UPDATE] 依存ライブラリの更新 28 | - `boost` を `1.83.0` に 29 | - `rapidcsv` を `8.77` に 30 | - @haruyama 31 | - [ADD] H.264 Track のサポート 32 | - @haruyama 33 | - [UPDATE] AV1 Track の調整 34 | - @haruyama 35 | 36 | ## 2023.1.1 37 | 38 | - [FIX] Version 上げ忘れを修正 #25 39 | - @haruyama 40 | - https://github.com/shiguredo/cpp-mp4/pull/25 41 | 42 | ## 2023.1.0 43 | 44 | - [UPDATE] 依存ライブラリの更新 45 | - `boost` を `1.81.0` に 46 | - `CLI11` を `2.3.2` に 47 | - `fmt` を `9.1.0` に 48 | - `spdlog` を `1.11.0` に 49 | - `rapidcsv` を `8.69` に 50 | - @haruyama 51 | - https://github.com/shiguredo/cpp-mp4/pull/20 52 | - [FIX] Safari, Windows Media Player などでの再生の問題を修正 53 | - @haruyama 54 | - https://github.com/shiguredo/cpp-mp4/pull/19 55 | - [FIX] typo の修正 56 | - @haruyama 57 | - https://github.com/shiguredo/cpp-mp4/pull/18 58 | 59 | ## 2022.1.0 60 | 61 | - [UPDATE] 依存ライブラリの更新 62 | - `boost` を `1.78.0` に 63 | - `CLI11` を `2.1.2` に 64 | - `fmt` を `8.0.1` に 65 | - `spdlog` を `1.9.2` に 66 | - `rapidcsv` を `8.53` に 67 | - @haruyama 68 | - [FIX] 宇宙船演算子を利用している箇所に #include を追加 69 | - @haruyama 70 | - https://github.com/shiguredo/cpp-mp4/pull/12 71 | 72 | ## 2021.3 73 | 74 | - [UPDATE] `boost` を `1.76.0` に 75 | - @haruyama 76 | - https://github.com/shiguredo/cpp-mp4/pull/8 77 | 78 | ## 2021.2 79 | 80 | - [ADD] av01, av1C box のサポート 81 | - @haruyama 82 | - [ADD] get_version_string() の追加 83 | - @haruyama 84 | - [UPDATE] `rapidcsv` を `8.48` に 85 | - @haruyama 86 | - [FIX] MP4 ファイルの読み込み時に, ファイル終端を越える box のサイズを指定されたら例外を投げる 87 | - @haruyama 88 | - [FIX] VPCodecConfiguration::getDataSize() のバグ修正 89 | - @haruyama 90 | 91 | ## 2021.1 92 | 93 | **祝リリース** 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cpp-mp4 2 | 3 | [![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/shiguredo/cpp-mp4.svg)](https://github.com/shiguredo/cpp-mp4) 4 | [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 5 | 6 | > [!IMPORTANT] 7 | > このライブラリはメンテナンスモードで、バグフィックスのみ対応します。 8 | 9 | > [!NOTE] 10 | > [shiguredo/mp4\-rust: MP4 library](https://github.com/shiguredo/mp4-rust) の利用を検討してください。 11 | 12 | 13 | ## About Shiguredo's open source software 14 | 15 | We will not respond to PRs or issues that have not been discussed on Discord. Also, Discord is only available in Japanese. 16 | 17 | Please read https://github.com/shiguredo/oss before use. 18 | 19 | ## 時雨堂のオープンソースソフトウェアについて 20 | 21 | 利用前に https://github.com/shiguredo/oss をお読みください。 22 | 23 | ## ライセンス 24 | 25 | Apache License 2.0 26 | 27 | ``` 28 | Copyright 2020-2025, Shiguredo Inc. 29 | Copyright 2020-2023, HARUYAMA Seigo (Original Author) 30 | 31 | Licensed under the Apache License, Version 2.0 (the "License"); 32 | you may not use this file except in compliance with the License. 33 | You may obtain a copy of the License at 34 | 35 | http://www.apache.org/licenses/LICENSE-2.0 36 | 37 | Unless required by applicable law or agreed to in writing, software 38 | distributed under the License is distributed on an "AS IS" BASIS, 39 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 40 | See the License for the specific language governing permissions and 41 | limitations under the License. 42 | ``` 43 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- 1 | sunfish-shogi 2 | uupaa 3 | -------------------------------------------------------------------------------- /cmake/REAME.md: -------------------------------------------------------------------------------- 1 | tools.cmake: from https://github.com/TheLartians/ModernCppStarter/tree/ed4ff7833a88ba5a7576958eb45cf6462cf2a69c/cmake 2 | 3 | Delete '# only activate tools for top level project' block: 4 | https://github.com/TheLartians/ModernCppStarter/blob/ed4ff7833a88ba5a7576958eb45cf6462cf2a69c/cmake/tools.cmake#L4 5 | -------------------------------------------------------------------------------- /cmake/env.cmake: -------------------------------------------------------------------------------- 1 | function(set_cache_string_from_env var default description) 2 | if(DEFINED ENV{${var}}) 3 | set(${var} $ENV{${var}} CACHE STRING ${description}) 4 | else() 5 | set(${var} ${default} CACHE STRING ${description}) 6 | endif() 7 | endfunction() 8 | -------------------------------------------------------------------------------- /cmake/tools.cmake: -------------------------------------------------------------------------------- 1 | # this file contains a list of tools that can be activated and downloaded on-demand each tool is 2 | # enabled during configuration by passing an additional `-DUSE_=` argument to CMake 3 | 4 | include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake) 5 | 6 | # enables sanitizers support using the the `USE_SANITIZER` flag available values are: Address, 7 | # Memory, MemoryWithOrigins, Undefined, Thread, Leak, 'Address;Undefined' 8 | if(USE_SANITIZER OR USE_STATIC_ANALYZER) 9 | CPMAddPackage( 10 | NAME StableCoder-cmake-scripts 11 | GITHUB_REPOSITORY StableCoder/cmake-scripts 12 | GIT_TAG 3d2d5a9fb26f0ce24e3e4eaeeff686ec2ecfb3fb 13 | ) 14 | 15 | if(USE_SANITIZER) 16 | include(${StableCoder-cmake-scripts_SOURCE_DIR}/sanitizers.cmake) 17 | endif() 18 | 19 | if(USE_STATIC_ANALYZER) 20 | if("clang-tidy" IN_LIST USE_STATIC_ANALYZER) 21 | set(CLANG_TIDY 22 | ON 23 | CACHE INTERNAL "" 24 | ) 25 | else() 26 | set(CLANG_TIDY 27 | OFF 28 | CACHE INTERNAL "" 29 | ) 30 | endif() 31 | if("iwyu" IN_LIST USE_STATIC_ANALYZER) 32 | set(IWYU 33 | ON 34 | CACHE INTERNAL "" 35 | ) 36 | else() 37 | set(IWYU 38 | OFF 39 | CACHE INTERNAL "" 40 | ) 41 | endif() 42 | if("cppcheck" IN_LIST USE_STATIC_ANALYZER) 43 | set(CPPCHECK 44 | ON 45 | CACHE INTERNAL "" 46 | ) 47 | else() 48 | set(CPPCHECK 49 | OFF 50 | CACHE INTERNAL "" 51 | ) 52 | endif() 53 | 54 | include(${StableCoder-cmake-scripts_SOURCE_DIR}/tools.cmake) 55 | 56 | clang_tidy(${CLANG_TIDY_ARGS}) 57 | include_what_you_use(${IWYU_ARGS}) 58 | cppcheck(${CPPCHECK_ARGS}) 59 | endif() 60 | endif() 61 | 62 | # enables CCACHE support through the USE_CCACHE flag possible values are: YES, NO or equivalent 63 | if(USE_CCACHE) 64 | CPMAddPackage( 65 | NAME Ccache.cmake 66 | GITHUB_REPOSITORY TheLartians/Ccache.cmake 67 | VERSION 1.2.1 68 | ) 69 | endif() 70 | -------------------------------------------------------------------------------- /example/resource/resource.cpp: -------------------------------------------------------------------------------- 1 | #include "resource/resource.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | std::vector hex2bin(const std::string& hex_data) { 14 | std::vector ret; 15 | ret.resize(std::size(hex_data) / 2); 16 | for (std::size_t i = 0; i < std::size(ret); ++i) { 17 | std::int16_t tmp; 18 | if (std::istringstream(hex_data.substr(i * 2, 2)) >> std::hex >> tmp) { 19 | ret[i] = static_cast(tmp); 20 | } 21 | } 22 | 23 | return ret; 24 | } 25 | 26 | void load_resources_from_csv(std::vector* resources, const std::string& filename) { 27 | resources->clear(); 28 | rapidcsv::Document doc(filename, rapidcsv::LabelParams(-1, -1)); 29 | resources->reserve(doc.GetRowCount()); 30 | for (std::size_t i = 0; i < doc.GetRowCount(); ++i) { 31 | const std::uint64_t timestamp = doc.GetCell(0, i); 32 | const std::size_t data_length = doc.GetCell(1, i); 33 | const std::string hex_data = doc.GetCell(2, i); 34 | const std::vector data = hex2bin(hex_data); 35 | if (data_length != std::size(data)) { 36 | throw new std::runtime_error(fmt::format("load_resources_from_csv(): data is invalid: timestamp={}", timestamp)); 37 | } 38 | bool is_key = true; 39 | if (doc.GetColumnCount() > 3) { 40 | is_key = doc.GetCell(3, i, [](const std::string& s, bool& val) { 41 | if (s == "true") { 42 | val = true; 43 | } else { 44 | val = false; 45 | } 46 | }); 47 | } 48 | resources->push_back(Resource{.timestamp = timestamp, .data = data, .is_key = is_key}); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /example/resource/resource.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct Resource { 8 | const std::uint64_t timestamp; 9 | const std::vector data; 10 | const bool is_key; 11 | }; 12 | 13 | void load_resources_from_csv(std::vector* resources, const std::string& filename); 14 | -------------------------------------------------------------------------------- /format.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # src/ test/ 以下のファイルに clang-format を適用する 4 | 5 | set -e 6 | 7 | shopt -s globstar 8 | 9 | for file in example/**/*.[ch]pp include/**/*.hpp src/**/*.[ch]pp test/**/*.[ch]pp; do 10 | echo applying "$file" 11 | clang-format -i -style=file "$file" 12 | done 13 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/bitio/reader.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace shiguredo::mp4::bitio { 8 | 9 | class Reader { 10 | public: 11 | explicit Reader(std::istream& t_is); 12 | 13 | std::streamsize read(std::vector* p); 14 | void readBits(std::vector* data, const std::uint64_t size); 15 | bool readBit(); 16 | std::uint64_t seek(const std::uint64_t offset, const std::ios_base::seekdir way); 17 | 18 | void setOctet(const std::uint8_t octet); 19 | std::uint8_t getOctet() const; 20 | 21 | void setWidth(const std::uint8_t width); 22 | 23 | std::istream& getIStream() const; 24 | 25 | private: 26 | std::istream& m_is; 27 | std::uint8_t m_octet = 0x00; 28 | std::uint8_t m_width = 0; 29 | }; 30 | 31 | } // namespace shiguredo::mp4::bitio 32 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/bitio/writer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace shiguredo::mp4::bitio { 8 | 9 | class Writer { 10 | public: 11 | explicit Writer(std::ostream& t_os); 12 | 13 | std::streamsize write(const std::vector& p); 14 | void writeBits(const std::vector& data, const std::uint64_t width); 15 | void writeBit(const bool bit); 16 | 17 | private: 18 | std::ostream& m_os; 19 | std::uint8_t m_octet = 0x00; 20 | std::uint64_t m_width = 0; 21 | }; 22 | 23 | } // namespace shiguredo::mp4::bitio 24 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include // NOLINT 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::bitio { 12 | 13 | class Reader; 14 | class Writer; 15 | 16 | } // namespace shiguredo::mp4::bitio 17 | 18 | namespace shiguredo::mp4 { 19 | 20 | class BoxHeader; 21 | 22 | class Box { 23 | public: 24 | virtual ~Box(); 25 | virtual std::uint8_t getVersion() const; 26 | virtual void setVersion(std::uint8_t); 27 | virtual std::uint32_t getFlags() const; 28 | virtual bool checkFlag(std::uint32_t) const; 29 | virtual void setFlags(std::uint32_t); 30 | virtual void addFlag(std::uint32_t); 31 | virtual void removeFlag(std::uint32_t); 32 | BoxType getType() const; 33 | virtual std::string toStringOnlyData() const = 0; 34 | std::string toString() const; 35 | std::uint64_t write(std::ostream&); 36 | virtual std::uint64_t writeData(std::ostream&) const = 0; 37 | virtual std::uint64_t readData(std::istream&) = 0; 38 | std::uint64_t getHeaderSize(); 39 | virtual std::uint64_t getDataSize() const; 40 | std::uint64_t getSize() const; 41 | 42 | void setHeader(BoxHeader*); 43 | void seekToData(std::istream& is); 44 | void seekToEnd(std::istream& is); 45 | void setOffsetAndDataSize(const std::uint64_t, const std::uint64_t); 46 | 47 | auto operator<=>(const Box&) const = default; 48 | 49 | protected: 50 | BoxType m_type; 51 | BoxHeader* m_header = nullptr; 52 | 53 | private: 54 | void makeHeader(); 55 | }; 56 | 57 | class FullBox : public Box { 58 | public: 59 | std::uint8_t getVersion() const override; 60 | void setVersion(std::uint8_t version) override; 61 | std::uint32_t getFlags() const override; 62 | std::string getVersionAndFlagsString() const; 63 | bool checkFlag(std::uint32_t flag) const override; 64 | void setFlags(std::uint32_t flag) override; 65 | void addFlag(std::uint32_t flag) override; 66 | void removeFlag(std::uint32_t flag) override; 67 | std::uint64_t writeVersionAndFlag(bitio::Writer*) const; 68 | std::uint64_t readVersionAndFlag(bitio::Reader*); 69 | std::uint64_t getDataSize() const override; 70 | 71 | auto operator<=>(const FullBox&) const = default; 72 | 73 | protected: 74 | std::uint8_t m_version = 0; 75 | std::array m_flags = {0, 0, 0}; 76 | }; 77 | 78 | class AnyTypeBox : public Box { 79 | public: 80 | void setType(const BoxType&); 81 | BoxType getType() const; 82 | 83 | auto operator<=>(const AnyTypeBox&) const = default; 84 | }; 85 | 86 | } // namespace shiguredo::mp4 87 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/av1c.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct AV1CodecConfigurationParameters { 14 | const std::uint8_t marker = 1; 15 | const std::uint8_t version = 1; 16 | const std::uint8_t seq_profile; 17 | const std::uint8_t seq_level_idx_0; 18 | const std::uint8_t seq_tier_0; 19 | const bool high_bitdepth = false; 20 | const bool twelve_bit = false; 21 | const bool monochrome = false; 22 | const std::uint8_t chroma_subsampling_x; 23 | const std::uint8_t chroma_subsampling_y; 24 | const std::uint8_t chroma_sample_position; 25 | const bool initial_presentation_delay_present = false; 26 | const std::uint8_t initial_presentation_delay_minus_one = 0; 27 | const std::vector config_OBUs = {}; 28 | }; 29 | 30 | BoxType box_type_av1c(); 31 | 32 | class AV1CodecConfiguration : public Box { 33 | public: 34 | AV1CodecConfiguration(); 35 | explicit AV1CodecConfiguration(const AV1CodecConfigurationParameters&); 36 | 37 | std::string toStringOnlyData() const override; 38 | 39 | std::uint64_t writeData(std::ostream&) const override; 40 | std::uint64_t readData(std::istream&) override; 41 | std::uint64_t getDataSize() const override; 42 | 43 | private: 44 | std::uint8_t m_marker = 1; 45 | std::uint8_t m_version = 1; 46 | std::uint8_t m_seq_profile; 47 | std::uint8_t m_seq_level_idx_0; 48 | std::uint8_t m_seq_tier_0; 49 | bool m_high_bitdepth; 50 | bool m_twelve_bit; 51 | bool m_monochrome; 52 | std::uint8_t m_chroma_subsampling_x; 53 | std::uint8_t m_chroma_subsampling_y; 54 | std::uint8_t m_chroma_sample_position; 55 | std::uint8_t m_reserved = 0; 56 | bool m_initial_presentation_delay_present; 57 | std::uint8_t m_initial_presentation_delay_minus_one; 58 | std::vector m_config_OBUs; 59 | }; 60 | 61 | } // namespace shiguredo::mp4::box 62 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/btrt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct BtrtParameters { 13 | const std::uint32_t decoding_buffer_size; 14 | const std::uint32_t max_bitrate; 15 | const std::uint32_t avg_bitrate; 16 | }; 17 | 18 | BoxType box_type_btrt(); 19 | 20 | class Btrt : public Box { 21 | public: 22 | Btrt(); 23 | explicit Btrt(const BtrtParameters&); 24 | 25 | std::string toStringOnlyData() const override; 26 | 27 | std::uint64_t writeData(std::ostream&) const override; 28 | std::uint64_t getDataSize() const override; 29 | std::uint64_t readData(std::istream&) override; 30 | 31 | private: 32 | std::uint32_t m_decoding_buffer_size; 33 | std::uint32_t m_max_bitrate; 34 | std::uint32_t m_avg_bitrate; 35 | }; 36 | 37 | } // namespace shiguredo::mp4::box 38 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/co64.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::box { 13 | 14 | struct Co64Parameters { 15 | const std::uint8_t version = 0; 16 | const std::uint32_t flags = 0x000000; 17 | const std::vector chunk_offsets; 18 | }; 19 | 20 | BoxType box_type_co64(); 21 | 22 | class Co64 : public FullBox { 23 | public: 24 | Co64(); 25 | explicit Co64(const Co64Parameters&); 26 | 27 | std::string toStringOnlyData() const override; 28 | 29 | std::uint64_t writeData(std::ostream& os) const override; 30 | std::uint64_t readData(std::istream& is) override; 31 | std::uint64_t getDataSize() const override; 32 | 33 | auto operator<=>(const Co64&) const = default; 34 | 35 | private: 36 | std::vector m_chunk_offsets; 37 | }; 38 | 39 | std::ostream& operator<<(std::ostream&, const Co64&); 40 | 41 | } // namespace shiguredo::mp4::box 42 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/colr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::bitio { 13 | 14 | class Reader; 15 | class Writer; 16 | 17 | } // namespace shiguredo::mp4::bitio 18 | 19 | namespace shiguredo::mp4::box { 20 | 21 | struct ColrParameters { 22 | const std::array colour_type; 23 | const std::uint16_t colour_primaries; 24 | const std::uint16_t transfer_characteristics; 25 | const std::uint16_t matrix_coefficients; 26 | const bool full_range_flag; 27 | const std::vector profile = {}; 28 | const std::vector unknown = {}; 29 | }; 30 | 31 | BoxType box_type_colr(); 32 | 33 | class Colr : public Box { 34 | public: 35 | Colr(); 36 | explicit Colr(const ColrParameters&); 37 | 38 | std::string toStringOnlyData() const override; 39 | 40 | std::uint64_t writeData(std::ostream& os) const override; 41 | std::uint64_t getDataSize() const override; 42 | std::uint64_t readData(std::istream& is) override; 43 | 44 | private: 45 | std::array m_colour_type; 46 | std::uint16_t m_colour_primaries; 47 | std::uint16_t m_transfer_characteristics; 48 | std::uint16_t m_matrix_coefficients; 49 | bool m_full_range_flag; 50 | std::uint8_t m_reserved = 0; 51 | std::vector m_profile; 52 | std::vector m_unknown; 53 | 54 | std::string nclxToString() const; 55 | std::string profileToString() const; 56 | std::string unknownToString() const; 57 | 58 | std::uint64_t nclxMarshal(bitio::Writer*) const; 59 | 60 | std::uint64_t nclxUnwriteData(bitio::Reader*); 61 | }; 62 | 63 | } // namespace shiguredo::mp4::box 64 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/ctts.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::bitio { 12 | 13 | class Reader; 14 | class Writer; 15 | 16 | } // namespace shiguredo::mp4::bitio 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | BoxType box_type_ctts(); 21 | 22 | class CttsEntry { 23 | public: 24 | CttsEntry() = default; 25 | CttsEntry(const std::uint32_t, const std::int64_t); 26 | 27 | std::string toString() const; 28 | std::uint64_t writeData(bitio::Writer*) const; 29 | std::uint64_t readData(bitio::Reader*); 30 | 31 | private: 32 | std::uint32_t m_sample_count; 33 | std::int64_t m_sample_offset; // size = 32 34 | }; 35 | 36 | struct CttsParameters { 37 | const std::uint8_t version = 0; 38 | const std::uint32_t flags = 0x000000; 39 | const std::vector entries; 40 | }; 41 | 42 | class Ctts : public FullBox { 43 | public: 44 | Ctts(); 45 | explicit Ctts(const CttsParameters&); 46 | 47 | std::string toStringOnlyData() const override; 48 | 49 | std::uint64_t writeData(std::ostream& os) const override; 50 | std::uint64_t getDataSize() const override; 51 | std::uint64_t readData(std::istream& is) override; 52 | 53 | private: 54 | std::vector m_entries; 55 | }; 56 | 57 | } // namespace shiguredo::mp4::box 58 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/dOps.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::bitio { 12 | 13 | class Reader; 14 | class Writer; 15 | 16 | } // namespace shiguredo::mp4::bitio 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | struct DOpsChannelMappingTableParameters { 21 | const std::uint8_t stream_count = 0; 22 | const std::uint8_t coupled_count = 0; 23 | const std::vector channel_mapping = {}; 24 | }; 25 | 26 | class DOpsChannelMappingTable { 27 | public: 28 | DOpsChannelMappingTable() = default; 29 | explicit DOpsChannelMappingTable(const DOpsChannelMappingTableParameters&); 30 | ~DOpsChannelMappingTable() = default; 31 | 32 | std::string toString() const; 33 | 34 | std::uint64_t writeData(bitio::Writer*) const; 35 | std::uint64_t getSize() const; 36 | std::uint64_t readData(bitio::Reader*, const std::uint8_t); 37 | 38 | private: 39 | std::uint8_t m_stream_count = 0; 40 | std::uint8_t m_coupled_count = 0; 41 | std::vector m_channel_mapping = {}; 42 | }; 43 | 44 | BoxType box_type_dOps(); 45 | 46 | struct DOpsParameters { 47 | const std::uint8_t version = 0; 48 | const std::uint8_t output_channel_count; 49 | const std::uint16_t pre_skip; 50 | const std::uint32_t input_sample_rate; 51 | const std::int16_t output_gain; 52 | const std::uint8_t channel_mapping_family; 53 | const DOpsChannelMappingTable channel_mapping_table = {}; 54 | }; 55 | 56 | class DOps : public Box { 57 | public: 58 | DOps(); 59 | explicit DOps(const DOpsParameters&); 60 | 61 | std::string toStringOnlyData() const override; 62 | 63 | std::uint64_t writeData(std::ostream&) const override; 64 | std::uint64_t getDataSize() const override; 65 | std::uint64_t readData(std::istream&) override; 66 | 67 | private: 68 | std::uint8_t m_version; 69 | std::uint8_t m_output_channel_count; 70 | std::uint16_t m_pre_skip; 71 | std::uint32_t m_input_sample_rate; 72 | std::int16_t m_output_gain; 73 | std::uint8_t m_channel_mapping_family; 74 | DOpsChannelMappingTable m_channel_mapping_table; 75 | }; 76 | 77 | } // namespace shiguredo::mp4::box 78 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/data.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::box { 13 | 14 | // https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW35 15 | enum DataType : std::uint32_t { 16 | Binary = 0, 17 | StringUTF8 = 1, 18 | StringUTF16 = 2, 19 | StringMac = 3, 20 | JPEG = 14, 21 | SignedIntBigEndian = 21, 22 | Float32BigEndian = 22, 23 | Float64BigEndian = 23, 24 | }; 25 | 26 | constexpr std::string_view data_type_to_string(DataType type) { 27 | using namespace std::string_view_literals; /* NOLINT */ 28 | switch (type) { 29 | case DataType::Binary: 30 | return "BINARY"sv; 31 | case DataType::StringUTF8: 32 | return "UTF8"sv; 33 | case DataType::StringUTF16: 34 | return "UTF16"sv; 35 | case DataType::StringMac: 36 | return "MAC_STR"sv; 37 | case DataType::JPEG: 38 | return "JPEG"sv; 39 | case DataType::SignedIntBigEndian: 40 | return "INT"sv; 41 | case DataType::Float32BigEndian: 42 | return "FLOAT32"sv; 43 | case DataType::Float64BigEndian: 44 | return "FLOAT64"sv; 45 | } 46 | return ""; 47 | } 48 | 49 | struct DataParameters { 50 | const DataType data_type = DataType::StringUTF8; 51 | const std::uint32_t data_lang = 0; 52 | const std::vector data; 53 | }; 54 | 55 | BoxType box_type_data(); 56 | 57 | class Data : public Box { 58 | public: 59 | Data(); 60 | explicit Data(const DataParameters&); 61 | 62 | std::string toStringOnlyData() const override; 63 | 64 | std::uint64_t writeData(std::ostream&) const override; 65 | std::uint64_t getDataSize() const override; 66 | std::uint64_t readData(std::istream&) override; 67 | 68 | private: 69 | DataType m_data_type; 70 | std::uint32_t m_data_lang; 71 | std::vector m_data; 72 | }; 73 | 74 | } // namespace shiguredo::mp4::box 75 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/dinf.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_dinf(); 13 | 14 | class Dinf : public Box { 15 | public: 16 | Dinf(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/dref.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct DrefParameters { 13 | const std::uint8_t version = 0; 14 | const std::uint32_t flags = 0x000000; 15 | const std::uint32_t entry_count; 16 | }; 17 | 18 | BoxType box_type_dref(); 19 | 20 | class Dref : public FullBox { 21 | public: 22 | Dref(); 23 | explicit Dref(const DrefParameters&); 24 | 25 | std::string toStringOnlyData() const override; 26 | 27 | std::uint64_t writeData(std::ostream&) const override; 28 | std::uint64_t getDataSize() const override; 29 | std::uint64_t readData(std::istream&) override; 30 | 31 | private: 32 | std::uint32_t m_entry_count; 33 | }; 34 | 35 | } // namespace shiguredo::mp4::box 36 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/edts.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_edts(); 13 | 14 | class Edts : public Box { 15 | public: 16 | Edts(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream& os) const override; 21 | std::uint64_t readData(std::istream& is) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/elst.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::bitio { 12 | 13 | class Reader; 14 | class Writer; 15 | 16 | } // namespace shiguredo::mp4::bitio 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | struct ElstEntryParameters { 21 | const std::uint64_t track_duration; 22 | const std::int64_t media_time = 0; 23 | const std::int32_t media_rate = 1 << 16; 24 | }; 25 | 26 | class ElstEntry { 27 | public: 28 | ElstEntry() = default; 29 | explicit ElstEntry(const ElstEntryParameters&); 30 | 31 | std::string toString() const; 32 | std::uint64_t writeData(bitio::Writer*, const std::uint8_t version) const; 33 | std::uint64_t getSize(const std::uint8_t version) const; 34 | std::uint64_t readData(bitio::Reader*, const std::uint8_t version); 35 | 36 | double getMediaRate() const; 37 | 38 | std::uint64_t m_track_duration; 39 | std::int64_t m_media_time; 40 | std::int32_t m_media_rate; 41 | }; 42 | 43 | BoxType box_type_elst(); 44 | 45 | struct ElstParameters { 46 | const std::uint8_t version = 0; 47 | const std::uint32_t flags = 0x000000; 48 | const std::vector entries; 49 | }; 50 | 51 | class Elst : public FullBox { 52 | public: 53 | Elst(); 54 | explicit Elst(const ElstParameters&); 55 | 56 | std::string toStringOnlyData() const override; 57 | 58 | std::uint64_t writeData(std::ostream& os) const override; 59 | std::uint64_t getDataSize() const override; 60 | std::uint64_t readData(std::istream& is) override; 61 | 62 | private: 63 | std::vector m_entries; 64 | }; 65 | 66 | } // namespace shiguredo::mp4::box 67 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/emsg.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct EmsgParameters { 14 | const std::uint8_t version = 0; 15 | const std::uint32_t flags = 0x000000; 16 | const std::string scheme_uri; 17 | const std::string value; 18 | const std::uint32_t timescale; 19 | const std::uint64_t presentation_time; 20 | const std::uint32_t event_duration; 21 | const std::uint32_t id; 22 | const std::vector message_data; 23 | }; 24 | 25 | BoxType box_type_emsg(); 26 | 27 | class Emsg : public FullBox { 28 | public: 29 | Emsg(); 30 | explicit Emsg(const EmsgParameters&); 31 | 32 | std::string toStringOnlyData() const override; 33 | 34 | std::uint64_t writeData(std::ostream& os) const override; 35 | std::uint64_t getDataSize() const override; 36 | std::uint64_t readData(std::istream& is) override; 37 | 38 | private: 39 | std::string m_scheme_uri; 40 | std::string m_value; 41 | std::uint32_t m_timescale; 42 | std::uint64_t m_presentation_time; 43 | std::uint32_t m_event_duration; 44 | std::uint32_t m_id; 45 | std::vector m_message_data; 46 | }; 47 | 48 | } // namespace shiguredo::mp4::box 49 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/fiel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct FielParameters { 13 | const std::uint8_t field_count = 1; 14 | const std::uint8_t field_ordering = 0; 15 | }; 16 | 17 | BoxType box_type_fiel(); 18 | 19 | class Fiel : public Box { 20 | public: 21 | Fiel(); 22 | explicit Fiel(const FielParameters&); 23 | 24 | std::string toStringOnlyData() const override; 25 | 26 | std::uint64_t writeData(std::ostream&) const override; 27 | std::uint64_t getDataSize() const override; 28 | std::uint64_t readData(std::istream&) override; 29 | 30 | private: 31 | std::uint8_t m_field_count; 32 | std::uint8_t m_field_ordering; 33 | }; 34 | 35 | } // namespace shiguredo::mp4::box 36 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/free.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct FreeParameters { 14 | const std::vector data; 15 | }; 16 | 17 | BoxType box_type_free(); 18 | 19 | class Free : public Box { 20 | public: 21 | Free(); 22 | explicit Free(const FreeParameters&); 23 | 24 | std::string toStringOnlyData() const override; 25 | 26 | std::uint64_t writeData(std::ostream& os) const override; 27 | std::uint64_t getDataSize() const override; 28 | std::uint64_t readData(std::istream& is) override; 29 | 30 | private: 31 | std::vector m_data; 32 | }; 33 | 34 | } // namespace shiguredo::mp4::box 35 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/ftyp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | #include "shiguredo/mp4/brand.hpp" 11 | 12 | namespace shiguredo::mp4::box { 13 | 14 | BoxType box_type_ftyp(); 15 | 16 | struct FtypParameters { 17 | const Brand major_brand; 18 | const std::uint32_t minor_version; 19 | const std::vector compatible_brands; 20 | }; 21 | 22 | class Ftyp : public Box { 23 | public: 24 | Ftyp(); 25 | explicit Ftyp(const FtypParameters& params); 26 | 27 | std::string toStringOnlyData() const override; 28 | 29 | std::uint64_t writeData(std::ostream& os) const override; 30 | std::uint64_t getDataSize() const override; 31 | std::uint64_t readData(std::istream& is) override; 32 | 33 | private: 34 | Brand m_major_brand; 35 | std::uint32_t m_minor_version; 36 | std::vector m_compatible_brands; 37 | }; 38 | 39 | } // namespace shiguredo::mp4::box 40 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/hdlr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::box { 13 | 14 | struct HdlrParameters { 15 | const std::uint8_t version = 0; 16 | const std::uint32_t flags = 0x000000; 17 | const std::uint32_t pre_defined = 0; 18 | const std::array handler_type; 19 | const std::string name; 20 | const std::vector padding = {}; 21 | }; 22 | 23 | BoxType box_type_hdlr(); 24 | 25 | class Hdlr : public FullBox { 26 | public: 27 | Hdlr(); 28 | explicit Hdlr(const HdlrParameters&); 29 | 30 | std::string toStringOnlyData() const override; 31 | 32 | std::uint64_t writeData(std::ostream& os) const override; 33 | std::uint64_t getDataSize() const override; 34 | std::uint64_t readData(std::istream& is) override; 35 | 36 | private: 37 | std::uint32_t m_pre_defined = 0; 38 | std::array m_handler_type; 39 | std::array m_manufacturer = {0, 0, 0, 0}; // Reserved. Set to 0. 40 | std::array m_flags = {0, 0, 0, 0}; // Reserved. Set to 0. 41 | std::array m_flags_mask = {0, 0, 0, 0}; // Reserved. Set to 0 42 | std::string m_name; 43 | std::vector m_padding = {}; 44 | }; 45 | 46 | } // namespace shiguredo::mp4::box 47 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/ilst.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct IlstMetaParameters { 13 | const BoxType type; 14 | }; 15 | 16 | class IlstMeta : public AnyTypeBox { 17 | public: 18 | IlstMeta() = default; 19 | explicit IlstMeta(const IlstMetaParameters&); 20 | std::string toStringOnlyData() const override; 21 | 22 | std::uint64_t writeData(std::ostream&) const override; 23 | std::uint64_t readData(std::istream&) override; 24 | }; 25 | 26 | BoxType box_type_ilst(); 27 | 28 | class Ilst : public Box { 29 | public: 30 | Ilst(); 31 | 32 | std::string toStringOnlyData() const override; 33 | 34 | std::uint64_t writeData(std::ostream&) const override; 35 | std::uint64_t readData(std::istream&) override; 36 | }; 37 | 38 | } // namespace shiguredo::mp4::box 39 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/iods.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct IodsParameters { 13 | const std::uint8_t version = 0; 14 | const std::uint32_t flags = 0x000000; 15 | const std::uint8_t type_tag; 16 | const std::uint32_t descriptor_length = 7; 17 | const std::uint16_t OD_ID; 18 | const std::uint8_t OD_profile_level; 19 | const std::uint8_t scene_profile_level; 20 | const std::uint8_t audio_profile_level; 21 | const std::uint8_t video_profile_level; 22 | const std::uint8_t graphics_profile_level; 23 | }; 24 | 25 | BoxType box_type_iods(); 26 | 27 | class Iods : public FullBox { 28 | public: 29 | Iods(); 30 | explicit Iods(const IodsParameters&); 31 | 32 | std::string toStringOnlyData() const override; 33 | 34 | std::uint64_t writeData(std::ostream&) const override; 35 | std::uint64_t getDataSize() const override; 36 | std::uint64_t readData(std::istream&) override; 37 | 38 | private: 39 | std::uint8_t m_type_tag; 40 | std::uint32_t m_descriptor_length; 41 | std::uint16_t m_OD_ID; 42 | std::uint8_t m_OD_profile_level; 43 | std::uint8_t m_scene_profile_level; 44 | std::uint8_t m_audio_profile_level; 45 | std::uint8_t m_video_profile_level; 46 | std::uint8_t m_graphics_profile_level; 47 | }; 48 | 49 | } // namespace shiguredo::mp4::box 50 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/mdat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct MdatParameters { 14 | const std::vector data; 15 | }; 16 | 17 | BoxType box_type_mdat(); 18 | 19 | class Mdat : public Box { 20 | public: 21 | Mdat(); 22 | explicit Mdat(const MdatParameters&); 23 | 24 | std::string toStringOnlyData() const override; 25 | 26 | std::uint64_t writeData(std::ostream&) const override; 27 | std::uint64_t getDataSize() const override; 28 | std::uint64_t readData(std::istream&) override; 29 | 30 | private: 31 | std::vector m_data; 32 | }; 33 | 34 | } // namespace shiguredo::mp4::box 35 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/mdhd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct MdhdParameters { 14 | const std::uint8_t version = 0; 15 | const std::uint32_t flags = 0x000000; 16 | const std::uint64_t creation_time; 17 | const std::uint64_t modification_time; 18 | const std::uint32_t timescale; 19 | const std::uint64_t duration; 20 | const bool pad = false; 21 | const std::array language = {'u', 'n', 'd'}; 22 | const std::uint16_t pre_defined = 0; 23 | }; 24 | 25 | BoxType box_type_mdhd(); 26 | 27 | class Mdhd : public FullBox { 28 | public: 29 | Mdhd(); 30 | explicit Mdhd(const MdhdParameters&); 31 | 32 | std::string toStringOnlyData() const override; 33 | 34 | std::uint64_t writeData(std::ostream&) const override; 35 | std::uint64_t getDataSize() const override; 36 | std::uint64_t readData(std::istream&) override; 37 | 38 | private: 39 | std::uint64_t m_creation_time; 40 | std::uint64_t m_modification_time; 41 | std::uint32_t m_timescale; 42 | std::uint64_t m_duration; 43 | bool m_pad; 44 | std::array m_language; 45 | std::uint16_t m_pre_defined; 46 | }; 47 | 48 | std::uint16_t encode_language(const std::array&); 49 | std::array decode_language(const std::uint16_t enc); 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/mdia.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_mdia(); 13 | 14 | class Mdia : public Box { 15 | public: 16 | Mdia(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/mehd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct MehdParameters { 13 | const std::uint8_t version = 0; 14 | const std::uint32_t flags = 0x000000; 15 | const std::uint64_t fragment_duration; 16 | }; 17 | 18 | BoxType box_type_mehd(); 19 | 20 | class Mehd : public FullBox { 21 | public: 22 | Mehd(); 23 | explicit Mehd(const MehdParameters&); 24 | 25 | std::string toStringOnlyData() const override; 26 | 27 | std::uint64_t writeData(std::ostream&) const override; 28 | std::uint64_t getDataSize() const override; 29 | std::uint64_t readData(std::istream&) override; 30 | 31 | private: 32 | std::uint64_t m_fragment_duration; 33 | }; 34 | 35 | } // namespace shiguredo::mp4::box 36 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/meta.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_meta(); 13 | 14 | class Meta : public FullBox { 15 | public: 16 | Meta(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/mfhd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct MfhdParameters { 13 | const std::uint8_t version = 0; 14 | const std::uint32_t flags = 0x000000; 15 | const std::uint32_t sequence_number; 16 | }; 17 | 18 | BoxType box_type_mfhd(); 19 | 20 | class Mfhd : public FullBox { 21 | public: 22 | Mfhd(); 23 | explicit Mfhd(const MfhdParameters&); 24 | 25 | std::string toStringOnlyData() const override; 26 | 27 | std::uint64_t writeData(std::ostream&) const override; 28 | std::uint64_t getDataSize() const override; 29 | std::uint64_t readData(std::istream&) override; 30 | 31 | private: 32 | std::uint32_t m_sequence_number; 33 | }; 34 | 35 | } // namespace shiguredo::mp4::box 36 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/mfra.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_mfra(); 13 | 14 | class Mfra : public Box { 15 | public: 16 | Mfra(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/mfro.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct MfroParameters { 13 | const std::uint8_t version = 0; 14 | const std::uint32_t flags = 0x000000; 15 | const std::uint32_t size; 16 | }; 17 | 18 | BoxType box_type_mfro(); 19 | 20 | class Mfro : public FullBox { 21 | public: 22 | Mfro(); 23 | explicit Mfro(const MfroParameters&); 24 | 25 | std::string toStringOnlyData() const override; 26 | 27 | std::uint64_t writeData(std::ostream&) const override; 28 | std::uint64_t getDataSize() const override; 29 | std::uint64_t readData(std::istream&) override; 30 | 31 | private: 32 | std::uint32_t m_size; 33 | }; 34 | 35 | } // namespace shiguredo::mp4::box 36 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/minf.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_minf(); 13 | 14 | class Minf : public Box { 15 | public: 16 | Minf(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/moof.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_moof(); 13 | 14 | class Moof : public Box { 15 | public: 16 | Moof(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/moov.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_moov(); 13 | 14 | class Moov : public Box { 15 | public: 16 | Moov(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/mvex.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_mvex(); 13 | 14 | class Mvex : public Box { 15 | public: 16 | Mvex(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/mvhd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct MvhdParameters { 14 | const std::uint8_t version = 0; 15 | const std::uint32_t flags = 0x000000; 16 | const std::uint64_t creation_time; 17 | const std::uint64_t modification_time; 18 | const std::uint32_t timescale = 600; 19 | const std::uint64_t duration; 20 | const std::int32_t rate = 1 << 16; 21 | const std::int16_t volume = 256; 22 | const std::array matrix = {1 << 16, 0, 0, 0, 1 << 16, 0, 0, 0, 1 << 30}; 23 | const std::array pre_defined = {0, 0, 0, 0, 0, 0}; 24 | const std::uint32_t next_track_id; 25 | }; 26 | 27 | BoxType box_type_mvhd(); 28 | 29 | class Mvhd : public FullBox { 30 | public: 31 | Mvhd(); 32 | explicit Mvhd(const MvhdParameters&); 33 | 34 | std::string toStringOnlyData() const override; 35 | 36 | std::uint64_t writeData(std::ostream&) const override; 37 | std::uint64_t getDataSize() const override; 38 | std::uint64_t readData(std::istream&) override; 39 | 40 | double getRate() const; 41 | 42 | void setNextTrackID(const std::uint32_t); 43 | 44 | private: 45 | std::uint64_t m_creation_time; 46 | std::uint64_t m_modification_time; 47 | std::uint32_t m_timescale; 48 | std::uint64_t m_duration; 49 | std::int32_t m_rate; 50 | std::int16_t m_volume; 51 | std::int16_t m_reserved = 0; 52 | std::uint32_t m_reserved2 = 0; 53 | std::uint32_t m_reserved3 = 0; 54 | std::array m_matrix; 55 | std::array m_pre_defined; 56 | std::uint32_t m_next_track_id; 57 | }; 58 | 59 | } // namespace shiguredo::mp4::box 60 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/pixel_aspect_ratio.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct PixelAspectRatioParameters { 13 | const std::uint32_t h_spacing = 1; 14 | const std::uint32_t v_spacing = 1; 15 | }; 16 | 17 | BoxType box_type_pasp(); 18 | 19 | class PixelAspectRatio : public AnyTypeBox { 20 | public: 21 | PixelAspectRatio(); 22 | explicit PixelAspectRatio(const PixelAspectRatioParameters&); 23 | 24 | std::string toStringOnlyData() const override; 25 | std::uint64_t writeData(std::ostream&) const override; 26 | std::uint64_t getDataSize() const override; 27 | std::uint64_t readData(std::istream&) override; 28 | 29 | private: 30 | std::uint32_t m_h_spacing; 31 | std::uint32_t m_v_spacing; 32 | }; 33 | 34 | } // namespace shiguredo::mp4::box 35 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/pssh.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::bitio { 13 | 14 | class Reader; 15 | class Writer; 16 | 17 | } // namespace shiguredo::mp4::bitio 18 | 19 | namespace shiguredo::mp4::box { 20 | 21 | struct PsshKIDParameters { 22 | const std::array kid; 23 | }; 24 | 25 | class PsshKID { 26 | public: 27 | PsshKID() = default; 28 | explicit PsshKID(const PsshKIDParameters&); 29 | std::string toString() const; 30 | std::uint64_t writeData(bitio::Writer*) const; 31 | std::uint64_t readData(bitio::Reader*); 32 | 33 | private: 34 | std::array m_kid; 35 | }; 36 | 37 | struct PsshParameters { 38 | const std::uint8_t version = 0; 39 | const std::uint32_t flags = 0x000000; 40 | const std::array system_id; 41 | const std::vector kids = {}; 42 | const std::vector data; 43 | }; 44 | 45 | BoxType box_type_pssh(); 46 | 47 | class Pssh : public FullBox { 48 | public: 49 | Pssh(); 50 | explicit Pssh(const PsshParameters&); 51 | 52 | std::string toStringOnlyData() const override; 53 | 54 | std::uint64_t writeData(std::ostream&) const override; 55 | std::uint64_t getDataSize() const override; 56 | std::uint64_t readData(std::istream&) override; 57 | 58 | private: 59 | std::array m_system_id; 60 | std::vector m_kids = {}; 61 | std::vector m_data; 62 | }; 63 | 64 | } // namespace shiguredo::mp4::box 65 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/sbgp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | #include "shiguredo/mp4/grouping_type.hpp" 11 | 12 | namespace shiguredo::mp4::bitio { 13 | 14 | class Reader; 15 | class Writer; 16 | 17 | } // namespace shiguredo::mp4::bitio 18 | 19 | namespace shiguredo::mp4::box { 20 | 21 | struct SbgpEntryParameters { 22 | const std::uint32_t sample_count; 23 | const std::uint32_t group_description_index; 24 | }; 25 | 26 | class SbgpEntry { 27 | public: 28 | SbgpEntry() = default; 29 | explicit SbgpEntry(const SbgpEntryParameters&); 30 | 31 | std::string toString() const; 32 | 33 | std::uint64_t writeData(bitio::Writer*) const; 34 | std::uint64_t readData(bitio::Reader*); 35 | 36 | private: 37 | std::uint32_t m_sample_count; 38 | std::uint32_t m_group_description_index; 39 | }; 40 | 41 | struct SbgpParameters { 42 | const std::uint8_t version = 0; 43 | const std::uint32_t flags = 0x000000; 44 | const GroupingType grouping_type = GroupingTypeRoll; 45 | const std::uint32_t grouping_type_parameter = 0; 46 | const std::vector entries; 47 | }; 48 | 49 | BoxType box_type_sbgp(); 50 | 51 | class Sbgp : public FullBox { 52 | public: 53 | Sbgp(); 54 | explicit Sbgp(const SbgpParameters&); 55 | 56 | std::string toStringOnlyData() const override; 57 | 58 | std::uint64_t writeData(std::ostream&) const override; 59 | std::uint64_t getDataSize() const override; 60 | std::uint64_t readData(std::istream&) override; 61 | 62 | private: 63 | GroupingType m_grouping_type; 64 | std::uint32_t m_grouping_type_parameter; 65 | std::vector m_entries; 66 | }; 67 | 68 | } // namespace shiguredo::mp4::box 69 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/schi.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_schi(); 13 | 14 | class Schi : public Box { 15 | public: 16 | Schi(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/sdtp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::bitio { 12 | 13 | class Reader; 14 | class Writer; 15 | 16 | } // namespace shiguredo::mp4::bitio 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | struct StdpSampleParameters { 21 | const std::uint8_t is_leading; 22 | const std::uint8_t sample_depends_on; 23 | const std::uint8_t sample_is_depended_on; 24 | const std::uint8_t sample_has_redundancy; 25 | }; 26 | 27 | class SdtpSample { 28 | public: 29 | SdtpSample() = default; 30 | explicit SdtpSample(const StdpSampleParameters&); 31 | 32 | std::string toString() const; 33 | 34 | std::uint64_t writeData(bitio::Writer*) const; 35 | std::uint64_t readData(bitio::Reader*); 36 | 37 | private: 38 | std::uint8_t m_is_leading; 39 | std::uint8_t m_sample_depends_on; 40 | std::uint8_t m_sample_is_depended_on; 41 | std::uint8_t m_sample_has_redundancy; 42 | }; 43 | 44 | struct SdtpParameters { 45 | const std::vector samples; 46 | }; 47 | 48 | BoxType box_type_sdtp(); 49 | 50 | class Sdtp : public FullBox { 51 | public: 52 | Sdtp(); 53 | explicit Sdtp(const SdtpParameters&); 54 | 55 | std::string toStringOnlyData() const override; 56 | 57 | std::uint64_t writeData(std::ostream&) const override; 58 | std::uint64_t getDataSize() const override; 59 | std::uint64_t readData(std::istream&) override; 60 | 61 | private: 62 | std::vector m_samples; 63 | }; 64 | 65 | } // namespace shiguredo::mp4::box 66 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/sidx.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::bitio { 12 | 13 | class Reader; 14 | class Writer; 15 | 16 | } // namespace shiguredo::mp4::bitio 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | struct SidxReferenceParameters { 21 | const bool reference_type; 22 | const std::uint32_t reference_size; 23 | const std::uint32_t subsegument_duration; 24 | const bool starts_with_sap; 25 | const std::uint8_t sap_type; 26 | const std::uint32_t sap_delta_time; 27 | }; 28 | 29 | class SidxReference { 30 | public: 31 | SidxReference() = default; 32 | explicit SidxReference(const SidxReferenceParameters&); 33 | 34 | std::string toString() const; 35 | 36 | std::uint64_t writeData(bitio::Writer*) const; 37 | std::uint64_t readData(bitio::Reader*); 38 | 39 | private: 40 | bool m_reference_type; 41 | std::uint32_t m_reference_size; 42 | std::uint32_t m_subsegument_duration; 43 | bool m_starts_with_sap; 44 | std::uint8_t m_sap_type; 45 | std::uint32_t m_sap_delta_time; 46 | }; 47 | 48 | struct SidxParameters { 49 | const std::uint8_t version = 0; 50 | const std::uint32_t flags = 0x000000; 51 | const std::uint32_t reference_id; 52 | const std::uint32_t timescale; 53 | const std::uint64_t earliest_presentation_time; 54 | const std::uint64_t first_offset; 55 | const std::vector references; 56 | }; 57 | 58 | BoxType box_type_sidx(); 59 | 60 | class Sidx : public FullBox { 61 | public: 62 | Sidx(); 63 | explicit Sidx(const SidxParameters&); 64 | 65 | std::string toStringOnlyData() const override; 66 | 67 | std::uint64_t writeData(std::ostream&) const override; 68 | std::uint64_t getDataSize() const override; 69 | std::uint64_t readData(std::istream&) override; 70 | 71 | private: 72 | std::uint32_t m_reference_id; 73 | std::uint32_t m_timescale; 74 | std::uint64_t m_earliest_presentation_time; 75 | std::uint64_t m_first_offset; 76 | std::uint16_t m_reserved = 0; 77 | std::vector m_references; 78 | }; 79 | 80 | } // namespace shiguredo::mp4::box 81 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/sinf.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_sinf(); 13 | 14 | class Sinf : public Box { 15 | public: 16 | Sinf(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/skip.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct SkipParameters { 14 | const std::vector data; 15 | }; 16 | 17 | BoxType box_type_skip(); 18 | 19 | class Skip : public Box { 20 | public: 21 | Skip(); 22 | explicit Skip(const SkipParameters&); 23 | 24 | std::string toStringOnlyData() const override; 25 | 26 | std::uint64_t writeData(std::ostream& os) const override; 27 | std::uint64_t getDataSize() const override; 28 | std::uint64_t readData(std::istream& is) override; 29 | 30 | private: 31 | std::vector m_data; 32 | }; 33 | 34 | } // namespace shiguredo::mp4::box 35 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/smhd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct SmhdParameters { 13 | const std::uint8_t version = 0; 14 | const std::uint32_t flags = 0x000000; 15 | const std::int16_t balance = 0; 16 | }; 17 | 18 | BoxType box_type_smhd(); 19 | 20 | class Smhd : public FullBox { 21 | public: 22 | Smhd(); 23 | explicit Smhd(const SmhdParameters&); 24 | 25 | std::string toStringOnlyData() const override; 26 | 27 | std::uint64_t writeData(std::ostream&) const override; 28 | std::uint64_t getDataSize() const override; 29 | std::uint64_t readData(std::istream&) override; 30 | 31 | float getBalance() const; 32 | 33 | private: 34 | std::int16_t m_balance; 35 | std::uint16_t m_reserved = 0; 36 | }; 37 | 38 | } // namespace shiguredo::mp4::box 39 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/stbl.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_stbl(); 13 | 14 | class Stbl : public Box { 15 | public: 16 | Stbl(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/stco.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::box { 13 | 14 | struct StcoParameters { 15 | const std::uint8_t version = 0; 16 | const std::uint32_t flags = 0x000000; 17 | const std::vector chunk_offsets; 18 | }; 19 | 20 | BoxType box_type_stco(); 21 | 22 | class Stco : public FullBox { 23 | public: 24 | Stco(); 25 | explicit Stco(const StcoParameters&); 26 | 27 | std::string toStringOnlyData() const override; 28 | 29 | std::uint64_t writeData(std::ostream&) const override; 30 | std::uint64_t readData(std::istream&) override; 31 | std::uint64_t getDataSize() const override; 32 | 33 | auto operator<=>(const Stco&) const = default; 34 | 35 | private: 36 | std::vector m_chunk_offsets; 37 | }; 38 | 39 | std::ostream& operator<<(std::ostream&, const Stco&); 40 | 41 | } // namespace shiguredo::mp4::box 42 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/stsc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::bitio { 13 | 14 | class Reader; 15 | class Writer; 16 | 17 | } // namespace shiguredo::mp4::bitio 18 | 19 | namespace shiguredo::mp4::box { 20 | 21 | struct StscEntryParameters { 22 | const std::uint32_t first_chunk; 23 | const std::uint32_t samples_per_chunk; 24 | const std::uint32_t sample_description_index = 1; 25 | }; 26 | 27 | class StscEntry { 28 | public: 29 | StscEntry() = default; 30 | explicit StscEntry(const StscEntryParameters&); 31 | 32 | std::string toString() const; 33 | 34 | std::uint64_t writeData(bitio::Writer*) const; 35 | std::uint64_t readData(bitio::Reader*); 36 | auto operator<=>(const StscEntry&) const = default; 37 | 38 | private: 39 | std::uint32_t m_first_chunk; 40 | std::uint32_t m_sample_per_chunk; 41 | std::uint32_t m_sample_description_index; 42 | }; 43 | 44 | std::ostream& operator<<(std::ostream&, const StscEntry&); 45 | 46 | struct StscParameters { 47 | const std::uint8_t version = 0; 48 | const std::uint32_t flags = 0x000000; 49 | const std::vector entries; 50 | }; 51 | 52 | BoxType box_type_stsc(); 53 | 54 | class Stsc : public FullBox { 55 | public: 56 | Stsc(); 57 | explicit Stsc(const StscParameters&); 58 | 59 | std::string toStringOnlyData() const override; 60 | 61 | std::uint64_t writeData(std::ostream&) const override; 62 | std::uint64_t getDataSize() const override; 63 | std::uint64_t readData(std::istream&) override; 64 | 65 | private: 66 | std::vector m_entries; 67 | }; 68 | 69 | } // namespace shiguredo::mp4::box 70 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/stsd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct StsdParameters { 13 | const std::uint8_t version = 0; 14 | const std::uint32_t flags = 0x000000; 15 | const std::uint32_t entry_count; 16 | }; 17 | 18 | BoxType box_type_stsd(); 19 | 20 | class Stsd : public FullBox { 21 | public: 22 | Stsd(); 23 | explicit Stsd(const StsdParameters&); 24 | 25 | std::string toStringOnlyData() const override; 26 | 27 | std::uint64_t writeData(std::ostream&) const override; 28 | std::uint64_t getDataSize() const override; 29 | std::uint64_t readData(std::istream&) override; 30 | 31 | private: 32 | std::uint32_t m_entry_count; 33 | }; 34 | 35 | } // namespace shiguredo::mp4::box 36 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/stss.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct StssParmeters { 14 | const std::uint8_t version = 0; 15 | const std::uint32_t flags = 0x000000; 16 | const std::vector& sample_numbers; 17 | }; 18 | 19 | BoxType box_type_stss(); 20 | 21 | class Stss : public FullBox { 22 | public: 23 | Stss(); 24 | explicit Stss(const StssParmeters&); 25 | 26 | std::string toStringOnlyData() const override; 27 | 28 | std::uint64_t writeData(std::ostream&) const override; 29 | std::uint64_t getDataSize() const override; 30 | std::uint64_t readData(std::istream&) override; 31 | 32 | private: 33 | std::vector m_sample_numbers; 34 | }; 35 | 36 | } // namespace shiguredo::mp4::box 37 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/stsz.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct StszParameters { 14 | const std::uint8_t version = 0; 15 | const std::uint32_t flags = 0x000000; 16 | const std::uint32_t sample_size = 0; 17 | const std::vector entry_sizes; 18 | }; 19 | 20 | BoxType box_type_stsz(); 21 | 22 | class Stsz : public FullBox { 23 | public: 24 | Stsz(); 25 | explicit Stsz(const StszParameters&); 26 | 27 | std::string toStringOnlyData() const override; 28 | 29 | std::uint64_t writeData(std::ostream&) const override; 30 | std::uint64_t getDataSize() const override; 31 | std::uint64_t readData(std::istream&) override; 32 | 33 | private: 34 | std::uint32_t m_sample_size; 35 | std::vector m_entry_sizes; 36 | }; 37 | 38 | } // namespace shiguredo::mp4::box 39 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/stts.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::bitio { 13 | 14 | class Reader; 15 | class Writer; 16 | 17 | } // namespace shiguredo::mp4::bitio 18 | 19 | namespace shiguredo::mp4::box { 20 | 21 | struct SttsEntryParameters { 22 | const std::uint32_t sample_count; 23 | const std::uint32_t sample_duration; 24 | }; 25 | 26 | class SttsEntry { 27 | public: 28 | SttsEntry() = default; 29 | explicit SttsEntry(const SttsEntryParameters&); 30 | 31 | std::string toString() const; 32 | 33 | std::uint64_t writeData(bitio::Writer*) const; 34 | std::uint64_t readData(bitio::Reader*); 35 | auto operator<=>(const SttsEntry&) const = default; 36 | 37 | private: 38 | std::uint32_t m_sample_count; 39 | std::uint32_t m_sample_duration; 40 | }; 41 | 42 | std::ostream& operator<<(std::ostream&, const SttsEntry&); 43 | 44 | struct SttsParameters { 45 | const std::uint8_t version = 0; 46 | const std::uint32_t flags = 0x000000; 47 | const std::vector entries; 48 | }; 49 | 50 | BoxType box_type_stts(); 51 | 52 | class Stts : public FullBox { 53 | public: 54 | Stts(); 55 | explicit Stts(const SttsParameters&); 56 | 57 | std::string toStringOnlyData() const override; 58 | 59 | std::uint64_t writeData(std::ostream&) const override; 60 | std::uint64_t getDataSize() const override; 61 | std::uint64_t readData(std::istream&) override; 62 | 63 | private: 64 | std::vector m_entries; 65 | }; 66 | 67 | } // namespace shiguredo::mp4::box 68 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/styp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | #include "shiguredo/mp4/brand.hpp" 11 | 12 | namespace shiguredo::mp4::box { 13 | 14 | struct StypParameters { 15 | const Brand major_brand; 16 | const std::uint32_t minor_version; 17 | const std::vector compatible_brands; 18 | }; 19 | 20 | BoxType box_type_styp(); 21 | 22 | class Styp : public Box { 23 | public: 24 | Styp(); 25 | explicit Styp(const StypParameters&); 26 | 27 | std::string toStringOnlyData() const override; 28 | 29 | std::uint64_t writeData(std::ostream&) const override; 30 | std::uint64_t getDataSize() const override; 31 | std::uint64_t readData(std::istream&) override; 32 | 33 | private: 34 | Brand m_major_brand; 35 | std::uint32_t m_minor_version; 36 | std::vector m_compatible_brands; 37 | }; 38 | 39 | } // namespace shiguredo::mp4::box 40 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/tfdt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct TfdtParameters { 13 | const std::uint8_t version = 0; 14 | const std::uint32_t flags = 0x000000; 15 | const std::uint64_t base_media_decode_time; 16 | }; 17 | 18 | BoxType box_type_tfdt(); 19 | 20 | class Tfdt : public FullBox { 21 | public: 22 | Tfdt(); 23 | explicit Tfdt(const TfdtParameters&); 24 | 25 | std::string toStringOnlyData() const override; 26 | 27 | std::uint64_t writeData(std::ostream&) const override; 28 | std::uint64_t getDataSize() const override; 29 | std::uint64_t readData(std::istream&) override; 30 | 31 | private: 32 | std::uint64_t m_base_media_decode_time; 33 | }; 34 | 35 | } // namespace shiguredo::mp4::box 36 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/tfhd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | enum TfhdFlags : std::uint32_t { 13 | TfhdBaseDataOffsetPresent = 0x000001, 14 | TfhdSampleDescriptionIndexPresent = 0x000002, 15 | TfhdDefaultSampleDurationPresent = 0x000008, 16 | TfhdDefaultSampleSizePresent = 0x000010, 17 | TfhdDefaultSampleFlagsPresent = 0x000020, 18 | TfhdDurationIsEmpty = 0x010000, 19 | TfhdDefaultBaseIsMoof = 0x020000, 20 | }; 21 | 22 | struct TfhdParameters { 23 | const std::uint8_t version = 0; 24 | const std::uint32_t flags = 0x000000; 25 | const std::uint32_t track_id; 26 | const std::uint64_t base_data_offset = 0; 27 | const std::uint32_t sample_description_index = 0; 28 | const std::uint32_t default_sample_duration = 0; 29 | const std::uint32_t default_sample_size = 0; 30 | const std::uint32_t default_sample_flags = 0; 31 | }; 32 | 33 | BoxType box_type_tfhd(); 34 | 35 | class Tfhd : public FullBox { 36 | public: 37 | Tfhd(); 38 | explicit Tfhd(const TfhdParameters&); 39 | 40 | std::string toStringOnlyData() const override; 41 | 42 | std::uint64_t writeData(std::ostream&) const override; 43 | std::uint64_t getDataSize() const override; 44 | std::uint64_t readData(std::istream&) override; 45 | 46 | private: 47 | std::uint32_t m_track_id; 48 | std::uint64_t m_base_data_offset; 49 | std::uint32_t m_sample_description_index; 50 | std::uint32_t m_default_sample_duration; 51 | std::uint32_t m_default_sample_size; 52 | std::uint32_t m_default_sample_flags; 53 | }; 54 | 55 | } // namespace shiguredo::mp4::box 56 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/tfra.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::bitio { 12 | 13 | class Reader; 14 | class Writer; 15 | 16 | } // namespace shiguredo::mp4::bitio 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | struct TfraEntryParameters { 21 | const std::uint64_t time; 22 | const std::uint64_t moof_offset; 23 | const std::uint32_t traf_number; 24 | const std::uint32_t trun_number; 25 | const std::uint32_t sample_number; 26 | }; 27 | 28 | class TfraEntry { 29 | public: 30 | TfraEntry() = default; 31 | explicit TfraEntry(const TfraEntryParameters&); 32 | 33 | std::string toString() const; 34 | 35 | std::uint64_t writeData(bitio::Writer*, 36 | const std::uint8_t, 37 | const std::uint8_t, 38 | const std::uint8_t, 39 | const std::uint8_t) const; 40 | std::uint64_t getSize(const std::uint8_t, const std::uint8_t, const std::uint8_t, const std::uint8_t) const; 41 | std::uint64_t readData(bitio::Reader*, 42 | const std::uint8_t, 43 | const std::uint8_t, 44 | const std::uint8_t, 45 | const std::uint8_t); 46 | 47 | private: 48 | std::uint64_t m_time; 49 | std::uint64_t m_moof_offset; 50 | std::uint32_t m_traf_number; 51 | std::uint32_t m_trun_number; 52 | std::uint32_t m_sample_number; 53 | }; 54 | 55 | struct TfraParameters { 56 | const std::uint8_t version = 0; 57 | const std::uint32_t flags = 0x000000; 58 | const std::uint32_t track_id; 59 | const std::uint8_t length_size_of_traf_num; 60 | const std::uint8_t length_size_of_trun_num; 61 | const std::uint8_t length_size_of_sample_num; 62 | const std::vector entries; 63 | }; 64 | 65 | BoxType box_type_tfra(); 66 | 67 | class Tfra : public FullBox { 68 | public: 69 | Tfra(); 70 | explicit Tfra(const TfraParameters&); 71 | 72 | std::string toStringOnlyData() const override; 73 | 74 | std::uint64_t writeData(std::ostream&) const override; 75 | std::uint64_t getDataSize() const override; 76 | std::uint64_t readData(std::istream&) override; 77 | 78 | private: 79 | std::uint32_t m_track_id; 80 | std::uint32_t m_reserved = 0; 81 | std::uint8_t m_length_size_of_traf_num; 82 | std::uint8_t m_length_size_of_trun_num; 83 | std::uint8_t m_length_size_of_sample_num; 84 | std::vector m_entries; 85 | }; 86 | 87 | } // namespace shiguredo::mp4::box 88 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/tkhd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct TkhdParameters { 14 | const std::uint8_t version = 0; 15 | const std::uint32_t flags = 0x000000; 16 | const std::uint64_t creation_time; 17 | const std::uint64_t modification_time; 18 | const std::uint32_t track_id; 19 | const std::uint64_t duration; 20 | const std::int16_t layer = 0; 21 | const std::int16_t alternate_group = 0; 22 | const std::int16_t volume = 256; 23 | const std::array matrix = {1 << 16, 0, 0, 0, 1 << 16, 0, 0, 0, 1 << 30}; 24 | const std::uint32_t width = 0; 25 | const std::uint32_t height = 0; 26 | }; 27 | 28 | BoxType box_type_tkhd(); 29 | 30 | class Tkhd : public FullBox { 31 | public: 32 | Tkhd(); 33 | explicit Tkhd(const TkhdParameters&); 34 | 35 | std::string toStringOnlyData() const override; 36 | 37 | std::uint64_t writeData(std::ostream&) const override; 38 | std::uint64_t getDataSize() const override; 39 | std::uint64_t readData(std::istream&) override; 40 | 41 | double getWidth() const; 42 | double getHeight() const; 43 | 44 | private: 45 | std::uint64_t m_creation_time; 46 | std::uint64_t m_modification_time; 47 | std::uint32_t m_track_id; 48 | std::uint32_t m_reserved = 0; 49 | std::uint64_t m_duration; 50 | std::uint32_t m_reserved2 = 0; 51 | std::uint32_t m_reserved3 = 0; 52 | std::int16_t m_layer; 53 | std::int16_t m_alternate_group; 54 | std::int16_t m_volume; 55 | std::uint16_t m_reserved4 = 0; 56 | std::array m_matrix; 57 | std::uint32_t m_width; 58 | std::uint32_t m_height; 59 | }; 60 | 61 | } // namespace shiguredo::mp4::box 62 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/traf.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_traf(); 13 | 14 | class Traf : public Box { 15 | public: 16 | Traf(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/trak.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_trak(); 13 | 14 | class Trak : public Box { 15 | public: 16 | Trak(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/trex.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | struct TrexParameters { 13 | const std::uint8_t version = 0; 14 | const std::uint32_t flags = 0x000000; 15 | const std::uint32_t track_id; 16 | const std::uint32_t default_sample_description_index; 17 | const std::uint32_t default_sample_duration; 18 | const std::uint32_t default_sample_size; 19 | const std::uint32_t default_sample_flags; 20 | }; 21 | 22 | BoxType box_type_trex(); 23 | 24 | class Trex : public FullBox { 25 | public: 26 | Trex(); 27 | explicit Trex(const TrexParameters&); 28 | 29 | std::string toStringOnlyData() const override; 30 | 31 | std::uint64_t writeData(std::ostream&) const override; 32 | std::uint64_t getDataSize() const override; 33 | std::uint64_t readData(std::istream&) override; 34 | 35 | private: 36 | std::uint32_t m_track_id; 37 | std::uint32_t m_default_sample_description_index; 38 | std::uint32_t m_default_sample_duration; 39 | std::uint32_t m_default_sample_size; 40 | std::uint32_t m_default_sample_flags; 41 | }; 42 | 43 | } // namespace shiguredo::mp4::box 44 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/trun.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::bitio { 12 | 13 | class Reader; 14 | class Writer; 15 | 16 | } // namespace shiguredo::mp4::bitio 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | struct TrunEntryParameters { 21 | const std::uint32_t sample_duration = 0; 22 | const std::uint32_t sample_size = 0; 23 | const std::uint32_t sample_flags = 0; 24 | const std::int64_t sample_composition_time_offset = 0; 25 | }; 26 | 27 | class TrunEntry { 28 | public: 29 | TrunEntry() = default; 30 | explicit TrunEntry(const TrunEntryParameters&); 31 | 32 | std::string toString(const std::uint32_t) const; 33 | std::uint64_t writeData(bitio::Writer*, const std::uint32_t) const; 34 | std::uint64_t getSize(const std::uint32_t) const; 35 | std::uint64_t readData(bitio::Reader*, const std::uint32_t); 36 | 37 | private: 38 | std::uint32_t m_sample_duration; 39 | std::uint32_t m_sample_size; 40 | std::uint32_t m_sample_flags; 41 | std::int64_t m_sample_composition_time_offset; 42 | }; 43 | 44 | struct TrunParameters { 45 | const std::uint8_t version = 0; 46 | const std::uint32_t flags = 0x000000; 47 | const std::int32_t data_offset = 0; 48 | const std::uint32_t first_sample_flags = 0; 49 | const std::vector entries = {}; 50 | }; 51 | 52 | BoxType box_type_trun(); 53 | 54 | class Trun : public FullBox { 55 | public: 56 | Trun(); 57 | explicit Trun(const TrunParameters&); 58 | 59 | std::string toStringOnlyData() const override; 60 | 61 | std::uint64_t writeData(std::ostream&) const override; 62 | std::uint64_t getDataSize() const override; 63 | std::uint64_t readData(std::istream&) override; 64 | 65 | private: 66 | std::int32_t m_data_offset; 67 | std::uint32_t m_first_sample_flags; 68 | std::vector m_entries; 69 | }; 70 | 71 | } // namespace shiguredo::mp4::box 72 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/udta.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_udta(); 13 | 14 | class Udta : public Box { 15 | public: 16 | Udta(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/unsupported.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct UnsupportedParameters { 14 | const std::vector data; 15 | }; 16 | 17 | BoxType box_type_unsupported(); 18 | 19 | class Unsupported : public Box { 20 | public: 21 | Unsupported(); 22 | explicit Unsupported(const UnsupportedParameters&); 23 | 24 | std::string toStringOnlyData() const override; 25 | 26 | std::uint64_t writeData(std::ostream&) const override; 27 | std::uint64_t getDataSize() const override; 28 | std::uint64_t readData(std::istream&) override; 29 | 30 | private: 31 | std::vector m_data; 32 | }; 33 | 34 | } // namespace shiguredo::mp4::box 35 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/url.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | const std::uint32_t UrlSelfContainedFlags = 0x000001; 13 | 14 | struct UrlParameters { 15 | const std::uint8_t version = 0; 16 | const std::uint32_t flags = 0x000000; 17 | const std::string location = ""; 18 | }; 19 | 20 | BoxType box_type_url(); 21 | 22 | class Url : public FullBox { 23 | public: 24 | Url(); 25 | explicit Url(const UrlParameters&); 26 | 27 | std::string toStringOnlyData() const override; 28 | 29 | std::uint64_t writeData(std::ostream& os) const override; 30 | std::uint64_t getDataSize() const override; 31 | std::uint64_t readData(std::istream& is) override; 32 | 33 | private: 34 | std::string m_location; 35 | }; 36 | 37 | } // namespace shiguredo::mp4::box 38 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/urn.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | const std::uint32_t UrnSelfContainedFlags = 0x000001; 13 | 14 | struct UrnParameters { 15 | const std::uint8_t version = 0; 16 | const std::uint32_t flags = 0x000000; 17 | const std::string name = ""; 18 | const std::string location = ""; 19 | }; 20 | 21 | BoxType box_type_urn(); 22 | 23 | class Urn : public FullBox { 24 | public: 25 | Urn(); 26 | explicit Urn(const UrnParameters&); 27 | 28 | std::string toStringOnlyData() const override; 29 | 30 | std::uint64_t writeData(std::ostream& os) const override; 31 | std::uint64_t getDataSize() const override; 32 | std::uint64_t readData(std::istream& is) override; 33 | 34 | private: 35 | std::string m_name; 36 | std::string m_location; 37 | }; 38 | 39 | } // namespace shiguredo::mp4::box 40 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/vmhd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct VmhdParameters { 14 | const std::uint8_t version = 0; 15 | const std::uint32_t flags = 0x000000; 16 | const std::uint16_t graphicsmode = 0; 17 | const std::array opcolor = {0, 0, 0}; 18 | }; 19 | 20 | BoxType box_type_vmhd(); 21 | 22 | class Vmhd : public FullBox { 23 | public: 24 | Vmhd(); 25 | explicit Vmhd(const VmhdParameters&); 26 | 27 | std::string toStringOnlyData() const override; 28 | 29 | std::uint64_t writeData(std::ostream&) const override; 30 | std::uint64_t getDataSize() const override; 31 | std::uint64_t readData(std::istream&) override; 32 | 33 | private: 34 | std::uint16_t m_graphicsmode; 35 | std::array m_opcolor; 36 | }; 37 | 38 | } // namespace shiguredo::mp4::box 39 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/vpc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box.hpp" 9 | #include "shiguredo/mp4/box_type.hpp" 10 | 11 | namespace shiguredo::mp4::box { 12 | 13 | struct VPCodecConfigurationParameters { 14 | const std::uint8_t version = 1; 15 | const std::uint32_t flags = 0x000000; 16 | const std::uint8_t profile = 0; 17 | const std::uint8_t level = 21; 18 | const std::uint8_t bit_depth = 8; 19 | const std::uint8_t chroma_sub_sampling = 1; 20 | const std::uint8_t video_full_range_flag = 0; 21 | const std::uint8_t colour_primaries = 2; 22 | const std::uint8_t transfer_characteristics = 2; 23 | const std::uint8_t matrix_coefficients = 2; 24 | const std::vector codec_initialization_data = {}; 25 | }; 26 | 27 | BoxType box_type_vpcc(); 28 | 29 | class VPCodecConfiguration : public FullBox { 30 | public: 31 | VPCodecConfiguration(); 32 | explicit VPCodecConfiguration(const VPCodecConfigurationParameters&); 33 | 34 | std::string toStringOnlyData() const override; 35 | 36 | std::uint64_t writeData(std::ostream&) const override; 37 | std::uint64_t readData(std::istream&) override; 38 | std::uint64_t getDataSize() const override; 39 | 40 | private: 41 | std::uint8_t m_profile; 42 | std::uint8_t m_level; 43 | std::uint8_t m_bit_depth; 44 | std::uint8_t m_chroma_sub_sampling; 45 | std::uint8_t m_video_full_range_flag; 46 | std::uint8_t m_colour_primaries; 47 | std::uint8_t m_transfer_characteristics; 48 | std::uint8_t m_matrix_coefficients; 49 | std::vector m_codec_initialization_data; 50 | }; 51 | 52 | } // namespace shiguredo::mp4::box 53 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box/wave.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box.hpp" 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4::box { 11 | 12 | BoxType box_type_wave(); 13 | 14 | class Wave : public Box { 15 | public: 16 | Wave(); 17 | 18 | std::string toStringOnlyData() const override; 19 | 20 | std::uint64_t writeData(std::ostream&) const override; 21 | std::uint64_t readData(std::istream&) override; 22 | }; 23 | 24 | } // namespace shiguredo::mp4::box 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box_header.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box_type.hpp" 9 | #include "shiguredo/mp4/constants.hpp" 10 | 11 | namespace shiguredo::mp4 { 12 | 13 | struct BoxHeaderParameters { 14 | const std::uint64_t offset = 0; 15 | const std::uint64_t size = 0; 16 | const std::uint64_t header_size = Constants::SMALL_HEADER_SIZE; 17 | const BoxType type; 18 | const bool extend_to_eof = false; 19 | }; 20 | 21 | class BoxHeader { 22 | public: 23 | explicit BoxHeader(const BoxHeaderParameters& t_type); 24 | 25 | void setOffsetAndDataSize(const std::uint64_t, const std::uint64_t); 26 | std::uint64_t write(std::ostream& os); 27 | 28 | void seekToData(std::istream& is); 29 | void seekToEnd(std::istream& is); 30 | 31 | auto operator<=>(const BoxHeader&) const = default; 32 | 33 | std::uint64_t getOffset() const; 34 | std::uint64_t getSize() const; 35 | std::uint64_t getDataSize() const; 36 | std::uint64_t getHeaderSize() const; 37 | BoxType getType() const; 38 | std::string toString() const; 39 | 40 | private: 41 | std::uint64_t m_offset; 42 | std::uint64_t m_size = 0; 43 | std::uint64_t m_header_size = Constants::SMALL_HEADER_SIZE; 44 | BoxType m_type; 45 | bool m_extend_to_eof = false; 46 | }; 47 | 48 | BoxHeader* read_box_header(std::istream&); 49 | 50 | } // namespace shiguredo::mp4 51 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box_info.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box_type.hpp" 9 | 10 | namespace shiguredo::mp4 { 11 | 12 | class Box; 13 | class BoxInfo; 14 | 15 | using BoxPath = std::vector; 16 | 17 | struct BoxInfoParameters { 18 | BoxInfo* parent = nullptr; 19 | Box* box; 20 | }; 21 | 22 | class BoxInfo { 23 | public: 24 | explicit BoxInfo(const BoxInfoParameters&); 25 | ~BoxInfo(); 26 | BoxPath getPath() const; 27 | Box* getBox() const; 28 | std::uint64_t getSize() const; 29 | BoxType getType() const; 30 | void addLeaf(BoxInfo*); 31 | std::string toString() const; 32 | std::uint64_t adjustOffsetAndSize(const std::uint64_t); 33 | void write(std::ostream&) const; 34 | 35 | private: 36 | BoxPath m_path; 37 | Box* m_box; 38 | std::vector m_leafs; 39 | }; 40 | 41 | } // namespace shiguredo::mp4 42 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box_map.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4 { 13 | 14 | class Box; 15 | class BoxHeader; 16 | 17 | typedef boost::function BoxFactory; 18 | 19 | struct BoxDefParameters { 20 | const BoxFactory factory; 21 | const std::vector versions; 22 | }; 23 | 24 | class BoxDef { 25 | public: 26 | explicit BoxDef(const BoxDefParameters&); 27 | BoxFactory factory; 28 | std::vector versions; 29 | }; 30 | 31 | class BoxMap { 32 | public: 33 | BoxMap() = default; 34 | 35 | void addBoxDef(const BoxFactory&, const BoxType&, const std::vector&); 36 | 37 | Box* getBoxInstance(const BoxType&); 38 | Box* getBoxInstance(BoxHeader*); 39 | bool isSupported(const BoxType& box_type) const; 40 | std::vector getSupportedVersions(const BoxType&) const; 41 | 42 | bool isSupportedVersion(const BoxType&, const std::uint8_t) const; 43 | 44 | private: 45 | std::map> m_map; 46 | }; 47 | 48 | } // namespace shiguredo::mp4 49 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include // NOLINT 5 | #include 6 | #include 7 | 8 | namespace shiguredo::mp4 { 9 | 10 | class BoxType { 11 | public: 12 | explicit BoxType(const std::string&); 13 | explicit BoxType(const std::array&); 14 | BoxType() = default; 15 | 16 | void setData(const std::uint8_t, const std::uint8_t, const std::uint8_t, const std::uint8_t); 17 | 18 | std::array getData() const; 19 | auto operator<=>(const BoxType&) const = default; 20 | 21 | std::string toString() const; 22 | bool matchWith(const BoxType& other) const; 23 | 24 | private: 25 | std::array m_data; 26 | }; 27 | 28 | BoxType box_type_any(); 29 | } // namespace shiguredo::mp4 30 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/box_types.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace shiguredo::mp4 { 4 | 5 | class BoxMap; 6 | 7 | void register_box_map(BoxMap*); 8 | 9 | } // namespace shiguredo::mp4 10 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/brand.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace shiguredo::mp4 { 7 | 8 | using Brand = std::array; 9 | 10 | const Brand BrandIsom{'i', 's', 'o', 'm'}; 11 | const Brand BrandIso2{'i', 's', 'o', '2'}; 12 | const Brand BrandMp41{'m', 'p', '4', '1'}; 13 | const Brand BrandMp42{'m', 'p', '4', '2'}; 14 | const Brand BrandAvc1{'a', 'v', 'c', '1'}; 15 | 16 | } // namespace shiguredo::mp4 17 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/constants.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace shiguredo::mp4 { 6 | 7 | class Constants { 8 | public: 9 | static const std::uint64_t SMALL_HEADER_SIZE = 8; 10 | static const std::uint64_t LARGE_HEADER_SIZE = 16; 11 | }; 12 | 13 | } // namespace shiguredo::mp4 14 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/endian/endian.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace shiguredo::mp4::endian { 7 | 8 | std::uint32_t be_to_uint32(const std::uint8_t d0, const std::uint8_t d1, const std::uint8_t d2, const std::uint8_t d3); 9 | std::uint32_t be_to_uint32(const std::array& a); 10 | 11 | std::uint64_t be_to_uint64(const std::uint8_t d0, 12 | const std::uint8_t d1, 13 | const std::uint8_t d2, 14 | const std::uint8_t d3, 15 | const std::uint8_t d4, 16 | const std::uint8_t d5, 17 | const std::uint8_t d6, 18 | const std::uint8_t d7); 19 | std::uint64_t be_to_uint64(const std::array& a); 20 | 21 | std::array uint32_to_be(const std::uint32_t i); 22 | std::array uint64_to_be(const std::uint64_t i); 23 | 24 | } // namespace shiguredo::mp4::endian 25 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/grouping_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace shiguredo::mp4 { 7 | 8 | using GroupingType = std::array; 9 | 10 | const GroupingType GroupingTypeRoll{'r', 'o', 'l', 'l'}; 11 | const GroupingType GroupingTypeProl{'p', 'r', 'o', 'l'}; 12 | const GroupingType GroupingTypeAlst{'a', 'l', 's', 't'}; 13 | const GroupingType GroupingTypeRap{'r', 'a', 'p', ' '}; 14 | const GroupingType GroupingTypeTele{'t', 'e', 'l', 'e'}; 15 | 16 | } // namespace shiguredo::mp4 17 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/reader/reader.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_map.hpp" 8 | 9 | namespace shiguredo::mp4 { 10 | 11 | class BoxInfo; 12 | 13 | } 14 | 15 | namespace shiguredo::mp4::reader { 16 | 17 | class SimpleReader { 18 | public: 19 | explicit SimpleReader(std::istream&); 20 | ~SimpleReader(); 21 | void read(); 22 | 23 | private: 24 | std::istream& m_is; 25 | BoxMap m_box_map; 26 | std::vector m_boxes; 27 | std::uint64_t m_total_size; 28 | 29 | std::uint64_t readBox(BoxInfo*); 30 | }; 31 | 32 | } // namespace shiguredo::mp4::reader 33 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/stream/stream.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace shiguredo::mp4::stream { 6 | 7 | std::streamoff get_istream_offset_to_end(std::istream&); 8 | 9 | } // namespace shiguredo::mp4::stream 10 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/time/time.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace shiguredo::mp4::time { 7 | 8 | const std::uint64_t SECONDS_19040101_to_19700101 = 2082844800; // 24107 * 86400 9 | 10 | std::string format_epoch_19040101(const std::uint64_t t); 11 | std::uint64_t convert_to_epoch_19040101(const std::uint64_t t); 12 | 13 | } // namespace shiguredo::mp4::time 14 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/track/aac.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "shiguredo/mp4/track/soun.hpp" 7 | 8 | namespace shiguredo::mp4 { 9 | 10 | class BoxInfo; 11 | 12 | namespace writer { 13 | 14 | class Writer; 15 | 16 | } 17 | 18 | } // namespace shiguredo::mp4 19 | 20 | namespace shiguredo::mp4::track { 21 | 22 | struct AACTrackParameters { 23 | const std::uint32_t timescale; 24 | const float duration; 25 | const std::int64_t media_time = 0; 26 | const std::uint32_t track_id = 0; 27 | const std::uint32_t buffer_size_db = 768; 28 | const std::uint32_t max_bitrate; 29 | const std::uint32_t avg_bitrate; 30 | shiguredo::mp4::writer::Writer* writer; 31 | }; 32 | 33 | class AACTrack : public SounTrack { 34 | public: 35 | explicit AACTrack(const AACTrackParameters&); 36 | void appendTrakBoxInfo(BoxInfo*) override; 37 | void addData(const std::uint64_t, const std::vector&, bool) override; 38 | void addData(const std::uint64_t, const std::uint8_t*, const std::size_t, bool) override; 39 | 40 | private: 41 | const std::uint32_t m_buffer_size_db; 42 | const std::uint32_t m_max_bitrate; 43 | const std::uint32_t m_avg_bitrate; 44 | const std::int16_t m_roll_distance = -1; 45 | void makeStsdBoxInfo(BoxInfo*); 46 | void makeSgpdBoxInfo(BoxInfo*); 47 | void makeSbgpBoxInfo(BoxInfo*); 48 | }; 49 | 50 | } // namespace shiguredo::mp4::track 51 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/track/av1.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "shiguredo/mp4/track/vide.hpp" 7 | 8 | namespace shiguredo::mp4 { 9 | 10 | class BoxInfo; 11 | 12 | namespace writer { 13 | 14 | class Writer; 15 | 16 | } 17 | 18 | } // namespace shiguredo::mp4 19 | 20 | namespace shiguredo::mp4::track { 21 | 22 | struct AV1TrackParameters { 23 | const std::uint32_t timescale; 24 | const std::int64_t media_time = 0; 25 | const float duration; 26 | const std::uint32_t track_id = 0; 27 | const std::uint32_t width; 28 | const std::uint32_t height; 29 | const std::uint8_t seq_profile = 0; 30 | const std::uint8_t seq_level_idx_0 = 0; 31 | const std::uint8_t seq_tier_0 = 0; 32 | const std::uint8_t chroma_subsampling_x = 1; 33 | const std::uint8_t chroma_subsampling_y = 1; 34 | const std::uint8_t chroma_sample_position = 0; 35 | const std::vector& config_OBUs = {0xa, 0xb, 0x0, 0x0, 0x0, 0x4, 0x47, 36 | 0x7e, 0x1a, 0xff, 0xfc, 0xc0, 0x20}; 37 | shiguredo::mp4::writer::Writer* writer; 38 | }; 39 | 40 | class AV1Track : public VideTrack { 41 | public: 42 | explicit AV1Track(const AV1TrackParameters&); 43 | void appendTrakBoxInfo(BoxInfo*) override; 44 | void addData(const std::uint64_t, const std::vector&, bool) override; 45 | void addData(const std::uint64_t, const std::uint8_t*, const std::size_t, bool) override; 46 | void setConfigOBUs(const std::vector&); 47 | 48 | private: 49 | std::uint8_t m_seq_profile; 50 | std::uint8_t m_seq_level_idx_0; 51 | std::uint8_t m_seq_tier_0; 52 | std::uint8_t m_chroma_subsampling_x; 53 | std::uint8_t m_chroma_subsampling_y; 54 | std::uint8_t m_chroma_sample_position; 55 | std::vector m_config_OBUs; 56 | void makeStsdBoxInfo(BoxInfo*); 57 | }; 58 | 59 | } // namespace shiguredo::mp4::track 60 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/track/h264.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "shiguredo/mp4/box/avc.hpp" 7 | #include "shiguredo/mp4/track/vide.hpp" 8 | 9 | namespace shiguredo::mp4 { 10 | 11 | class BoxInfo; 12 | 13 | namespace writer { 14 | 15 | class Writer; 16 | 17 | } 18 | 19 | } // namespace shiguredo::mp4 20 | 21 | namespace shiguredo::mp4::track { 22 | 23 | struct H264TrackParameters { 24 | const std::uint32_t timescale; 25 | const std::int64_t media_time = 0; 26 | const float duration; 27 | const std::uint32_t track_id = 0; 28 | const std::uint32_t width; 29 | const std::uint32_t height; 30 | const std::uint8_t configuration_version = 0x1; 31 | const std::uint8_t profile = box::AvcProfiles::AVCBaselineProfile; 32 | const std::uint8_t profile_compatibility = 0xc0; 33 | const std::uint8_t level = 31; 34 | shiguredo::mp4::writer::Writer* writer; 35 | }; 36 | 37 | class H264Track : public VideTrack { 38 | public: 39 | explicit H264Track(const H264TrackParameters&); 40 | void appendTrakBoxInfo(BoxInfo*) override; 41 | void addData(const std::uint64_t, const std::vector&, bool) override; 42 | void addData(const std::uint64_t, const std::uint8_t*, const std::size_t, bool) override; 43 | 44 | private: 45 | void makeStsdBoxInfo(BoxInfo*); 46 | void appendSequenceParameterSets(const shiguredo::mp4::box::AVCParameterSet&); 47 | void appendPictureParameterSets(const shiguredo::mp4::box::AVCParameterSet&); 48 | 49 | std::uint8_t m_configuration_version; 50 | std::uint8_t m_profile; 51 | std::uint8_t m_profile_compatibility; 52 | std::uint8_t m_level; 53 | std::vector m_sequence_parameter_sets = {}; 54 | std::vector m_picture_parameter_sets = {}; 55 | }; 56 | 57 | struct NalUnit { 58 | std::size_t start_code_size; 59 | std::size_t start; 60 | std::size_t end; 61 | std::uint8_t header; 62 | }; 63 | 64 | bool operator==(NalUnit const& left, NalUnit const& right); 65 | 66 | std::ostream& operator<<(std::ostream& os, const NalUnit& nu); 67 | 68 | NalUnit find_next_nal_unit(const std::uint8_t*, const std::size_t, const std::size_t); 69 | 70 | } // namespace shiguredo::mp4::track 71 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/track/mp3.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "shiguredo/mp4/track/soun.hpp" 7 | 8 | namespace shiguredo::mp4 { 9 | 10 | class BoxInfo; 11 | 12 | namespace writer { 13 | 14 | class Writer; 15 | 16 | } 17 | 18 | } // namespace shiguredo::mp4 19 | 20 | namespace shiguredo::mp4::track { 21 | 22 | struct MP3TrackParameters { 23 | const std::uint32_t timescale; 24 | const float duration; 25 | const std::int64_t media_time = 0; 26 | const std::uint32_t track_id = 0; 27 | const std::uint32_t buffer_size_db = 768; 28 | const std::uint32_t max_bitrate; 29 | const std::uint32_t avg_bitrate; 30 | shiguredo::mp4::writer::Writer* writer; 31 | }; 32 | 33 | class MP3Track : public SounTrack { 34 | public: 35 | explicit MP3Track(const MP3TrackParameters&); 36 | void appendTrakBoxInfo(BoxInfo*) override; 37 | void addData(const std::uint64_t, const std::vector&, bool) override; 38 | void addData(const std::uint64_t, const std::uint8_t*, const std::size_t, bool) override; 39 | 40 | private: 41 | const std::uint32_t m_buffer_size_db; 42 | const std::uint32_t m_max_bitrate; 43 | const std::uint32_t m_avg_bitrate; 44 | void makeStsdBoxInfo(BoxInfo*); 45 | }; 46 | 47 | } // namespace shiguredo::mp4::track 48 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/track/opus.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "shiguredo/mp4/track/soun.hpp" 7 | 8 | namespace shiguredo::mp4 { 9 | 10 | class BoxInfo; 11 | 12 | namespace writer { 13 | 14 | class Writer; 15 | } 16 | 17 | } // namespace shiguredo::mp4 18 | 19 | namespace shiguredo::mp4::track { 20 | 21 | struct OpusTrackParameters { 22 | const std::uint64_t pre_skip; 23 | const float duration; 24 | const std::int64_t media_time = 0; 25 | const std::int16_t roll_distance = -4; 26 | const std::uint32_t track_id = 0; 27 | shiguredo::mp4::writer::Writer* writer; 28 | }; 29 | 30 | class OpusTrack : public SounTrack { 31 | public: 32 | explicit OpusTrack(const OpusTrackParameters&); 33 | void appendTrakBoxInfo(BoxInfo*) override; 34 | void addData(const std::uint64_t, const std::vector&, bool) override; 35 | void addData(const std::uint64_t, const std::uint8_t*, const std::size_t, bool) override; 36 | 37 | private: 38 | const std::uint64_t m_pre_skip; 39 | const std::int16_t m_roll_distance; 40 | 41 | void makeStsdBoxInfo(BoxInfo*); 42 | void makeSgpdBoxInfo(BoxInfo*); 43 | void makeSbgpBoxInfo(BoxInfo*); 44 | }; 45 | 46 | } // namespace shiguredo::mp4::track 47 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/track/soun.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "shiguredo/mp4/track/track.hpp" 4 | 5 | namespace shiguredo::mp4 { 6 | 7 | class BoxInfo; 8 | 9 | } 10 | 11 | namespace shiguredo::mp4::track { 12 | 13 | class SounTrack : public Track { 14 | protected: 15 | SounTrack(); 16 | void makeTkhdBoxInfo(BoxInfo*) override; 17 | void makeSmhdBoxInfo(BoxInfo*); 18 | }; 19 | 20 | } // namespace shiguredo::mp4::track 21 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/track/vide.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "shiguredo/mp4/track/track.hpp" 6 | 7 | namespace shiguredo::mp4 { 8 | 9 | class BoxInfo; 10 | 11 | } 12 | 13 | namespace shiguredo::mp4::track { 14 | 15 | class VideTrack : public Track { 16 | protected: 17 | VideTrack(); 18 | void makeTkhdBoxInfo(BoxInfo*) override; 19 | void makeVmhdBoxInfo(BoxInfo*); 20 | std::uint32_t m_width; 21 | std::uint32_t m_height; 22 | std::uint32_t m_max_bitrate; 23 | std::uint32_t m_avg_bitrate; 24 | }; 25 | 26 | } // namespace shiguredo::mp4::track 27 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/track/vpx.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "shiguredo/mp4/track/vide.hpp" 7 | 8 | namespace shiguredo::mp4 { 9 | 10 | class BoxInfo; 11 | 12 | namespace writer { 13 | 14 | class Writer; 15 | 16 | } 17 | 18 | } // namespace shiguredo::mp4 19 | 20 | namespace shiguredo::mp4::track { 21 | 22 | enum VPXCodec { 23 | VP8, 24 | VP9, 25 | }; 26 | 27 | struct VPXTrackParameters { 28 | const VPXCodec codec = VPXCodec::VP9; 29 | const std::uint32_t timescale; 30 | const std::int64_t media_time = 0; 31 | const float duration; 32 | const std::uint32_t track_id = 0; 33 | const std::uint32_t width; 34 | const std::uint32_t height; 35 | const std::uint32_t max_bitrate = 0; 36 | const std::uint32_t avg_bitrate = 0; 37 | shiguredo::mp4::writer::Writer* writer; 38 | }; 39 | 40 | class VPXTrack : public VideTrack { 41 | public: 42 | explicit VPXTrack(const VPXTrackParameters&); 43 | void appendTrakBoxInfo(BoxInfo*) override; 44 | void addData(const std::uint64_t, const std::vector&, bool) override; 45 | void addData(const std::uint64_t, const std::uint8_t*, const std::size_t, bool) override; 46 | 47 | private: 48 | const VPXCodec m_codec; 49 | 50 | void makeStsdBoxInfo(BoxInfo*); 51 | }; 52 | 53 | } // namespace shiguredo::mp4::track 54 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/version.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace shiguredo::mp4 { 6 | 7 | std::string get_version_string(); 8 | 9 | } // namespace shiguredo::mp4 10 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/writer/faststart_writer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "shiguredo/mp4/box/ftyp.hpp" 10 | #include "shiguredo/mp4/brand.hpp" 11 | #include "shiguredo/mp4/writer/writer.hpp" 12 | 13 | namespace shiguredo::mp4::track { 14 | 15 | class Track; 16 | 17 | } 18 | 19 | namespace shiguredo::mp4::writer { 20 | 21 | const std::size_t COPY_MDAT_DATA_BUFFER_SIZE = 1024 * 1024; 22 | 23 | struct FaststartWriterParameters { 24 | const std::uint32_t mvhd_timescale = 1000; 25 | const float duration; 26 | const std::string mdat_path_templete = "mdatXXXXXX"; 27 | const box::FtypParameters ftyp_params{.major_brand = BrandIsom, 28 | .minor_version = 512, 29 | .compatible_brands = {BrandIsom, BrandIso2, BrandMp41}}; 30 | }; 31 | 32 | class FaststartWriter : public Writer { 33 | public: 34 | FaststartWriter(std::ostream&, const FaststartWriterParameters&); 35 | 36 | void writeFtypBox() override; 37 | void writeMoovBox() override; 38 | 39 | void addMdatData(const std::uint8_t*, const std::size_t) override; 40 | std::uint64_t tellCurrentMdatOffset() override; 41 | 42 | void appendTrakAndUdtaBoxInfo(const std::vector&) override; 43 | void writeMdatHeader(); 44 | void copyMdatData(); 45 | void deleteIntermediateFile(); 46 | std::filesystem::path getIntermediateFilePath(); 47 | 48 | private: 49 | std::ostream& m_os; 50 | const box::FtypParameters m_ftyp_params; 51 | std::filesystem::path m_mdat_path; 52 | std::FILE* m_mdat_fd; 53 | 54 | void setOffsetAndSize() override; 55 | 56 | void recreateMoovBoxInfo(); 57 | std::uint64_t getFtypSize() const; 58 | std::uint64_t getMoovSize() const; 59 | std::uint64_t getMdatHeaderSize() const; 60 | }; 61 | 62 | } // namespace shiguredo::mp4::writer 63 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/writer/simple_writer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box/ftyp.hpp" 8 | #include "shiguredo/mp4/brand.hpp" 9 | #include "shiguredo/mp4/writer/writer.hpp" 10 | 11 | namespace shiguredo::mp4::track { 12 | 13 | class Track; 14 | 15 | } 16 | 17 | namespace shiguredo::mp4::writer { 18 | 19 | struct SimpleWriterParameters { 20 | const std::uint32_t mvhd_timescale = 1000; 21 | const float duration; 22 | const box::FtypParameters ftyp_params{.major_brand = BrandIsom, 23 | .minor_version = 512, 24 | .compatible_brands = {BrandIsom, BrandIso2, BrandMp41}}; 25 | }; 26 | 27 | class SimpleWriter : public Writer { 28 | public: 29 | SimpleWriter(std::ostream&, const SimpleWriterParameters&); 30 | 31 | void writeFtypBox() override; 32 | void writeMoovBox() override; 33 | void writeFreeBoxAndMdatHeader(); 34 | 35 | void addMdatData(const std::uint8_t*, const std::size_t) override; 36 | std::uint64_t tellCurrentMdatOffset() override; 37 | 38 | void appendTrakAndUdtaBoxInfo(const std::vector&) override; 39 | 40 | private: 41 | std::ostream& m_os; 42 | const box::FtypParameters m_ftyp_params; 43 | 44 | void setOffsetAndSize() override; 45 | }; 46 | 47 | } // namespace shiguredo::mp4::writer 48 | -------------------------------------------------------------------------------- /include/shiguredo/mp4/writer/writer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box/data.hpp" 8 | #include "shiguredo/mp4/box/ftyp.hpp" 9 | 10 | namespace shiguredo::mp4 { 11 | 12 | class BoxInfo; 13 | 14 | namespace box { 15 | 16 | class Mvhd; 17 | 18 | } // namespace box 19 | 20 | namespace track { 21 | 22 | class Track; 23 | 24 | } 25 | 26 | } // namespace shiguredo::mp4 27 | 28 | namespace shiguredo::mp4::writer { 29 | 30 | class Writer { 31 | public: 32 | virtual ~Writer(); 33 | 34 | virtual void writeFtypBox() = 0; 35 | virtual void writeMoovBox() = 0; 36 | 37 | virtual void addMdatData(const std::uint8_t*, const std::size_t) = 0; 38 | void addMdatData(const std::vector&); 39 | virtual std::uint64_t tellCurrentMdatOffset() = 0; 40 | 41 | virtual void appendTrakAndUdtaBoxInfo(const std::vector&) = 0; 42 | 43 | void appendUdtaBoxInfo(const box::DataParameters& data_params = { 44 | .data = {'s', 'h', 'i', 'g', 'u', 'r', 'e', 'd', 'o', ':', ':', 'm', 'p', '4'}}); 45 | void addBoxesUnderMoov(BoxInfo*); 46 | 47 | BoxInfo* getMoovBoxInfo() const; 48 | std::uint64_t getTimeFromEpoch() const; 49 | std::uint32_t getMvhdTimescale() const; 50 | std::uint32_t getAndUpdateNextTrackID(); 51 | 52 | protected: 53 | std::uint32_t m_mvhd_timescale; 54 | float m_duration; 55 | std::uint64_t m_time_from_epoch; 56 | std::uint64_t m_ftyp_size; 57 | std::uint64_t m_mdat_data_size = 0; 58 | std::uint32_t m_next_track_id = 1; 59 | 60 | BoxInfo* m_moov_box_info = nullptr; 61 | box::Mvhd* m_mvhd_box; 62 | 63 | virtual void setOffsetAndSize() = 0; 64 | }; 65 | 66 | } // namespace shiguredo::mp4::writer 67 | -------------------------------------------------------------------------------- /lint.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | shopt -s globstar 6 | 7 | targets=(include/**/*.hpp example/**/*.[ch]pp src/**/*.[ch]pp test/**/*.[ch]pp) 8 | 9 | cpplint --linelength=120 --filter=-build/include_subdir,-legal/copyright,-build/c++11,-whitespace/braces "${targets[@]}" || exit 1 10 | misspell -error "${targets[@]}" || exit 1 11 | shellcheck ./**/*.bash || exit 1 12 | -------------------------------------------------------------------------------- /src/bitio/writer.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/bitio/writer.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace shiguredo::mp4::bitio { 12 | 13 | Writer::Writer(std::ostream& t_os) : m_os(t_os) {} 14 | 15 | std::streamsize Writer::write(const std::vector& p) { 16 | if (m_width != 0) { 17 | throw std::invalid_argument("bitio::Writer::write(): width is not 0"); 18 | } 19 | 20 | auto size = static_cast(std::size(p)); 21 | m_os.write(reinterpret_cast(p.data()), size); 22 | 23 | if (!m_os.good()) { 24 | throw std::runtime_error( 25 | fmt::format("bitio::Writer::write(): ostream::write() failed: rdstate={}", m_os.rdstate())); 26 | } 27 | 28 | return size; 29 | } 30 | 31 | void Writer::writeBits(const std::vector& data, const std::uint64_t width) { 32 | auto length = std::size(data) * 8; 33 | auto offset = length - width; 34 | for (auto i = offset; i < length; ++i) { 35 | auto oi = i >> 3; 36 | writeBit(((data[oi] >> (7 - i % 8)) & 0x01) != 0); 37 | } 38 | } 39 | 40 | void Writer::writeBit(const bool bit) { 41 | if (bit) { 42 | m_octet |= (0x1 << (7 - m_width)); 43 | } 44 | ++m_width; 45 | 46 | if (m_width == 8) { 47 | char data[1] = {static_cast(m_octet)}; 48 | m_os.write(data, 1); 49 | if (!m_os.good()) { 50 | throw std::runtime_error( 51 | fmt::format("bitio::Writer::writeBit(): ostream::write() failed: rdstate={}", m_os.rdstate())); 52 | } 53 | 54 | m_octet = 0x00; 55 | m_width = 0; 56 | } 57 | } 58 | 59 | } // namespace shiguredo::mp4::bitio 60 | -------------------------------------------------------------------------------- /src/box/btrt.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/btrt.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_btrt() { 18 | return BoxType("btrt"); 19 | } 20 | 21 | Btrt::Btrt(const BtrtParameters& params) 22 | : m_decoding_buffer_size(params.decoding_buffer_size), 23 | m_max_bitrate(params.max_bitrate), 24 | m_avg_bitrate(params.avg_bitrate) { 25 | m_type = box_type_btrt(); 26 | } 27 | 28 | Btrt::Btrt() { 29 | m_type = box_type_btrt(); 30 | } 31 | 32 | std::string Btrt::toStringOnlyData() const { 33 | return fmt::format("DecodingBufferSize={} MaxBitrate={} AvgBitrate={}", m_decoding_buffer_size, m_max_bitrate, 34 | m_avg_bitrate); 35 | } 36 | 37 | std::uint64_t Btrt::writeData(std::ostream& os) const { 38 | bitio::Writer writer(os); 39 | return bitio::write_uint(&writer, m_decoding_buffer_size) + 40 | bitio::write_uint(&writer, m_max_bitrate) + 41 | bitio::write_uint(&writer, m_avg_bitrate); 42 | } 43 | 44 | std::uint64_t Btrt::getDataSize() const { 45 | return 12; 46 | } 47 | 48 | std::uint64_t Btrt::readData(std::istream& is) { 49 | bitio::Reader reader(is); 50 | return bitio::read_uint(&reader, &m_decoding_buffer_size) + 51 | bitio::read_uint(&reader, &m_max_bitrate) + 52 | bitio::read_uint(&reader, &m_avg_bitrate); 53 | } 54 | 55 | } // namespace shiguredo::mp4::box 56 | -------------------------------------------------------------------------------- /src/box/co64.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/co64.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "shiguredo/mp4/bitio/bitio.hpp" 13 | #include "shiguredo/mp4/bitio/reader.hpp" 14 | #include "shiguredo/mp4/bitio/writer.hpp" 15 | #include "shiguredo/mp4/box_type.hpp" 16 | 17 | namespace shiguredo::mp4::box { 18 | 19 | BoxType box_type_co64() { 20 | return BoxType("co64"); 21 | } 22 | 23 | Co64::Co64() { 24 | m_type = box_type_co64(); 25 | } 26 | 27 | Co64::Co64(const Co64Parameters& params) : m_chunk_offsets(params.chunk_offsets) { 28 | setVersion(params.version); 29 | setFlags(params.flags); 30 | m_type = box_type_co64(); 31 | } 32 | 33 | std::string Co64::toStringOnlyData() const { 34 | return fmt::format("{} EntryCount={} ChunkOffsets=[{:#x}]", getVersionAndFlagsString(), std::size(m_chunk_offsets), 35 | fmt::join(m_chunk_offsets, ", ")); 36 | } 37 | 38 | std::uint64_t Co64::writeData(std::ostream& os) const { 39 | bitio::Writer writer(os); 40 | std::uint64_t wbits = writeVersionAndFlag(&writer); 41 | wbits += bitio::write_uint(&writer, static_cast(std::size(m_chunk_offsets))); 42 | wbits += bitio::write_vector_uint(&writer, m_chunk_offsets); 43 | return wbits; 44 | } 45 | 46 | std::uint64_t Co64::readData(std::istream& is) { 47 | bitio::Reader reader(is); 48 | std::uint64_t rbits = readVersionAndFlag(&reader); 49 | 50 | std::uint32_t entry_count; 51 | rbits += bitio::read_uint(&reader, &entry_count); 52 | rbits += bitio::read_vector_uint(&reader, entry_count, &m_chunk_offsets); 53 | return rbits; 54 | } 55 | 56 | std::uint64_t Co64::getDataSize() const { 57 | return 8 + std::size(m_chunk_offsets) * 8; 58 | } 59 | 60 | std::ostream& operator<<(std::ostream& os, const Co64& co64) { 61 | os << co64.toString(); 62 | return os; 63 | } 64 | 65 | } // namespace shiguredo::mp4::box 66 | -------------------------------------------------------------------------------- /src/box/data.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/data.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "shiguredo/mp4/bitio/bitio.hpp" 14 | #include "shiguredo/mp4/bitio/reader.hpp" 15 | #include "shiguredo/mp4/bitio/writer.hpp" 16 | #include "shiguredo/mp4/box_type.hpp" 17 | #include "shiguredo/mp4/stream/stream.hpp" 18 | 19 | namespace shiguredo::mp4::box { 20 | 21 | BoxType box_type_data() { 22 | return BoxType("data"); 23 | } 24 | 25 | Data::Data() { 26 | m_type = box_type_data(); 27 | } 28 | 29 | Data::Data(const DataParameters& params) 30 | : m_data_type(params.data_type), m_data_lang(params.data_lang), m_data(params.data) { 31 | m_type = box_type_data(); 32 | } 33 | 34 | std::string Data::toStringOnlyData() const { 35 | std::string s = fmt::format("DataType={} DataLang={} ", data_type_to_string(m_data_type), m_data_lang); 36 | if (m_data_type == StringUTF8) { 37 | std::vector escaped; 38 | std::transform(std::begin(m_data), std::end(m_data), std::back_inserter(escaped), [](const std::uint8_t c) { 39 | if (std::isprint(c)) { 40 | return c; 41 | } 42 | return static_cast('.'); 43 | }); 44 | std::string d(std::begin(escaped), std::end(escaped)); 45 | return s + fmt::format(R"(Data="{}")", d); 46 | } 47 | 48 | return s + fmt::format("Data=[{:#x}]", fmt::join(m_data, ", ")); 49 | } 50 | 51 | std::uint64_t Data::writeData(std::ostream& os) const { 52 | bitio::Writer writer(os); 53 | auto wbits = bitio::write_uint(&writer, m_data_type); 54 | wbits += bitio::write_uint(&writer, m_data_lang); 55 | return wbits + bitio::write_vector_uint(&writer, m_data); 56 | } 57 | 58 | std::uint64_t Data::readData(std::istream& is) { 59 | bitio::Reader reader(is); 60 | std::uint32_t data_type; 61 | auto rbits = bitio::read_uint(&reader, &data_type); 62 | m_data_type = static_cast(data_type); 63 | rbits += bitio::read_uint(&reader, &m_data_lang); 64 | const std::size_t offset_to_end = static_cast(shiguredo::mp4::stream::get_istream_offset_to_end(is)); 65 | return rbits + bitio::read_vector_uint(&reader, offset_to_end, &m_data); 66 | } 67 | 68 | std::uint64_t Data::getDataSize() const { 69 | return 8 + std::size(m_data); 70 | } 71 | 72 | } // namespace shiguredo::mp4::box 73 | -------------------------------------------------------------------------------- /src/box/dinf.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/dinf.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_dinf() { 12 | return BoxType("dinf"); 13 | } 14 | 15 | Dinf::Dinf() { 16 | m_type = box_type_dinf(); 17 | } 18 | 19 | std::string Dinf::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Dinf::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Dinf::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/dref.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/dref.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_dref() { 18 | return BoxType("dref"); 19 | } 20 | 21 | Dref::Dref() { 22 | m_type = box_type_dref(); 23 | } 24 | 25 | Dref::Dref(const DrefParameters& params) : m_entry_count(params.entry_count) { 26 | setVersion(params.version); 27 | setFlags(params.flags); 28 | m_type = box_type_dref(); 29 | } 30 | 31 | std::string Dref::toStringOnlyData() const { 32 | return fmt::format("{} EntryCount={}", getVersionAndFlagsString(), m_entry_count); 33 | } 34 | 35 | std::uint64_t Dref::writeData(std::ostream& os) const { 36 | bitio::Writer writer(os); 37 | std::uint64_t wbits = writeVersionAndFlag(&writer); 38 | return wbits + bitio::write_uint(&writer, m_entry_count); 39 | } 40 | 41 | std::uint64_t Dref::readData(std::istream& is) { 42 | bitio::Reader reader(is); 43 | std::uint64_t rbits = readVersionAndFlag(&reader); 44 | return rbits + bitio::read_uint(&reader, &m_entry_count); 45 | } 46 | 47 | std::uint64_t Dref::getDataSize() const { 48 | return 8; 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/edts.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/edts.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_edts() { 12 | return BoxType("edts"); 13 | } 14 | 15 | Edts::Edts() { 16 | m_type = box_type_edts(); 17 | } 18 | 19 | std::string Edts::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Edts::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Edts::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/fiel.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/fiel.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_fiel() { 18 | return BoxType("fiel"); 19 | } 20 | 21 | Fiel::Fiel(const FielParameters& params) : m_field_count(params.field_count), m_field_ordering(params.field_ordering) { 22 | m_type = box_type_fiel(); 23 | } 24 | 25 | Fiel::Fiel() { 26 | m_type = box_type_fiel(); 27 | } 28 | 29 | std::string Fiel::toStringOnlyData() const { 30 | return fmt::format("FieldCount={} FieldOrdering={}", m_field_count, m_field_ordering); 31 | } 32 | 33 | std::uint64_t Fiel::writeData(std::ostream& os) const { 34 | bitio::Writer writer(os); 35 | return bitio::write_uint(&writer, m_field_count) + 36 | bitio::write_uint(&writer, m_field_ordering); 37 | } 38 | 39 | std::uint64_t Fiel::getDataSize() const { 40 | return 2; 41 | } 42 | 43 | std::uint64_t Fiel::readData(std::istream& is) { 44 | bitio::Reader reader(is); 45 | return bitio::read_uint(&reader, &m_field_count) + 46 | bitio::read_uint(&reader, &m_field_ordering); 47 | } 48 | 49 | } // namespace shiguredo::mp4::box 50 | -------------------------------------------------------------------------------- /src/box/free.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/free.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "shiguredo/mp4/bitio/bitio.hpp" 13 | #include "shiguredo/mp4/bitio/reader.hpp" 14 | #include "shiguredo/mp4/bitio/writer.hpp" 15 | #include "shiguredo/mp4/box_type.hpp" 16 | #include "shiguredo/mp4/stream/stream.hpp" 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | BoxType box_type_free() { 21 | return BoxType("free"); 22 | } 23 | 24 | Free::Free() { 25 | m_type = box_type_free(); 26 | } 27 | 28 | Free::Free(const FreeParameters& params) : m_data(params.data) { 29 | m_type = box_type_free(); 30 | } 31 | 32 | std::string Free::toStringOnlyData() const { 33 | return fmt::format("Data=[{:#x}]", fmt::join(m_data, ", ")); 34 | } 35 | 36 | std::uint64_t Free::writeData(std::ostream& os) const { 37 | bitio::Writer writer(os); 38 | return bitio::write_vector_uint(&writer, m_data); 39 | } 40 | 41 | std::uint64_t Free::readData(std::istream& is) { 42 | bitio::Reader reader(is); 43 | const std::size_t offset_to_end = static_cast(shiguredo::mp4::stream::get_istream_offset_to_end(is)); 44 | return bitio::read_vector_uint(&reader, offset_to_end, &m_data); 45 | } 46 | 47 | std::uint64_t Free::getDataSize() const { 48 | return std::size(m_data); 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/ilst.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/ilst.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_ilst() { 12 | return BoxType("ilst"); 13 | } 14 | 15 | Ilst::Ilst() { 16 | m_type = box_type_ilst(); 17 | } 18 | 19 | IlstMeta::IlstMeta(const IlstMetaParameters& params) { 20 | m_type = params.type; 21 | } 22 | 23 | std::string Ilst::toStringOnlyData() const { 24 | return ""; 25 | } 26 | 27 | std::uint64_t Ilst::writeData(std::ostream&) const { 28 | return 0; 29 | } 30 | 31 | std::uint64_t Ilst::readData(std::istream&) { 32 | return 0; 33 | } 34 | 35 | std::string IlstMeta::toStringOnlyData() const { 36 | return ""; 37 | } 38 | 39 | std::uint64_t IlstMeta::writeData(std::ostream&) const { 40 | return 0; 41 | } 42 | 43 | std::uint64_t IlstMeta::readData(std::istream&) { 44 | return 0; 45 | } 46 | 47 | } // namespace shiguredo::mp4::box 48 | -------------------------------------------------------------------------------- /src/box/mdat.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/mdat.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "shiguredo/mp4/bitio/bitio.hpp" 13 | #include "shiguredo/mp4/bitio/reader.hpp" 14 | #include "shiguredo/mp4/bitio/writer.hpp" 15 | #include "shiguredo/mp4/box_type.hpp" 16 | #include "shiguredo/mp4/stream/stream.hpp" 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | BoxType box_type_mdat() { 21 | return BoxType("mdat"); 22 | } 23 | 24 | Mdat::Mdat() { 25 | m_type = box_type_mdat(); 26 | } 27 | 28 | Mdat::Mdat(const MdatParameters& params) : m_data(params.data) { 29 | m_type = box_type_mdat(); 30 | } 31 | 32 | std::string Mdat::toStringOnlyData() const { 33 | return fmt::format("Data=[{:#x}]", fmt::join(m_data, ", ")); 34 | } 35 | 36 | std::uint64_t Mdat::writeData(std::ostream& os) const { 37 | bitio::Writer writer(os); 38 | return bitio::write_vector_uint(&writer, m_data); 39 | } 40 | 41 | std::uint64_t Mdat::getDataSize() const { 42 | return std::size(m_data); 43 | } 44 | 45 | std::uint64_t Mdat::readData(std::istream& is) { 46 | bitio::Reader reader(is); 47 | const std::size_t offset_to_end = static_cast(shiguredo::mp4::stream::get_istream_offset_to_end(is)); 48 | return bitio::read_vector_uint(&reader, offset_to_end, &m_data); 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/mdia.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/mdia.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_mdia() { 12 | return BoxType("mdia"); 13 | } 14 | 15 | Mdia::Mdia() { 16 | m_type = box_type_mdia(); 17 | } 18 | 19 | std::string Mdia::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Mdia::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Mdia::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/mehd.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/mehd.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_mehd() { 18 | return BoxType("mehd"); 19 | } 20 | 21 | Mehd::Mehd() { 22 | m_type = box_type_mehd(); 23 | } 24 | 25 | Mehd::Mehd(const MehdParameters& params) : m_fragment_duration(params.fragment_duration) { 26 | setVersion(params.version); 27 | setFlags(params.flags); 28 | m_type = box_type_mehd(); 29 | } 30 | 31 | std::string Mehd::toStringOnlyData() const { 32 | return fmt::format("{} FragmentDuration={}", getVersionAndFlagsString(), m_fragment_duration); 33 | } 34 | 35 | std::uint64_t Mehd::writeData(std::ostream& os) const { 36 | bitio::Writer writer(os); 37 | std::uint64_t wbits = writeVersionAndFlag(&writer); 38 | return wbits + bitio::write_uint(&writer, m_fragment_duration, m_version == 0 ? 32 : 64); 39 | } 40 | 41 | std::uint64_t Mehd::getDataSize() const { 42 | return 4 + (m_version == 0 ? 4 : 8); 43 | } 44 | 45 | std::uint64_t Mehd::readData(std::istream& is) { 46 | bitio::Reader reader(is); 47 | std::uint64_t rbits = readVersionAndFlag(&reader); 48 | return rbits + bitio::read_uint(&reader, &m_fragment_duration, m_version == 0 ? 32 : 64); 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/meta.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/meta.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/bitio/reader.hpp" 9 | #include "shiguredo/mp4/bitio/writer.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::box { 13 | 14 | BoxType box_type_meta() { 15 | return BoxType("meta"); 16 | } 17 | 18 | Meta::Meta() { 19 | m_type = box_type_meta(); 20 | } 21 | 22 | std::string Meta::toStringOnlyData() const { 23 | return getVersionAndFlagsString(); 24 | } 25 | 26 | std::uint64_t Meta::writeData(std::ostream& os) const { 27 | bitio::Writer writer(os); 28 | return writeVersionAndFlag(&writer); 29 | } 30 | 31 | std::uint64_t Meta::readData(std::istream& is) { 32 | bitio::Reader reader(is); 33 | std::uint64_t rbits = readVersionAndFlag(&reader); 34 | if ((m_version | m_flags[0] | m_flags[1] | m_flags[2]) != 0) { 35 | m_version = 0; 36 | m_flags = {0, 0, 0}; 37 | } 38 | 39 | return rbits; 40 | } 41 | 42 | } // namespace shiguredo::mp4::box 43 | -------------------------------------------------------------------------------- /src/box/mfhd.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/mfhd.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_mfhd() { 18 | return BoxType("mfhd"); 19 | } 20 | 21 | Mfhd::Mfhd() { 22 | m_type = box_type_mfhd(); 23 | } 24 | 25 | Mfhd::Mfhd(const MfhdParameters& params) : m_sequence_number(params.sequence_number) { 26 | setVersion(params.version); 27 | setFlags(params.flags); 28 | m_type = box_type_mfhd(); 29 | } 30 | 31 | std::string Mfhd::toStringOnlyData() const { 32 | return fmt::format("{} SequenceNumber={}", getVersionAndFlagsString(), m_sequence_number); 33 | } 34 | 35 | std::uint64_t Mfhd::writeData(std::ostream& os) const { 36 | bitio::Writer writer(os); 37 | std::uint64_t wbits = writeVersionAndFlag(&writer); 38 | return wbits + bitio::write_uint(&writer, m_sequence_number); 39 | } 40 | 41 | std::uint64_t Mfhd::readData(std::istream& is) { 42 | bitio::Reader reader(is); 43 | std::uint64_t rbits = readVersionAndFlag(&reader); 44 | return rbits + bitio::read_uint(&reader, &m_sequence_number); 45 | } 46 | 47 | std::uint64_t Mfhd::getDataSize() const { 48 | return 8; 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/mfra.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/mfra.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_mfra() { 12 | return BoxType("mfra"); 13 | } 14 | 15 | Mfra::Mfra() { 16 | m_type = box_type_mfra(); 17 | } 18 | 19 | std::string Mfra::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Mfra::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Mfra::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/mfro.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/mfro.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_mfro() { 18 | return BoxType("mfro"); 19 | } 20 | 21 | Mfro::Mfro() { 22 | m_type = box_type_mfro(); 23 | } 24 | 25 | Mfro::Mfro(const MfroParameters& params) : m_size(params.size) { 26 | setVersion(params.version); 27 | setFlags(params.flags); 28 | m_type = box_type_mfro(); 29 | } 30 | 31 | std::string Mfro::toStringOnlyData() const { 32 | return fmt::format("{} Size={}", getVersionAndFlagsString(), m_size); 33 | } 34 | 35 | std::uint64_t Mfro::writeData(std::ostream& os) const { 36 | bitio::Writer writer(os); 37 | std::uint64_t wbits = writeVersionAndFlag(&writer); 38 | return wbits + bitio::write_uint(&writer, m_size); 39 | } 40 | 41 | std::uint64_t Mfro::readData(std::istream& is) { 42 | bitio::Reader reader(is); 43 | std::uint64_t rbits = readVersionAndFlag(&reader); 44 | return rbits + bitio::read_uint(&reader, &m_size); 45 | } 46 | 47 | std::uint64_t Mfro::getDataSize() const { 48 | return 8; 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/minf.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/minf.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_minf() { 12 | return BoxType("minf"); 13 | } 14 | 15 | Minf::Minf() { 16 | m_type = box_type_minf(); 17 | } 18 | 19 | std::string Minf::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Minf::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Minf::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/moof.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/moof.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_moof() { 12 | return BoxType("moof"); 13 | } 14 | 15 | Moof::Moof() { 16 | m_type = box_type_moof(); 17 | } 18 | 19 | std::string Moof::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Moof::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Moof::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/moov.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/moov.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_moov() { 12 | return BoxType("moov"); 13 | } 14 | 15 | Moov::Moov() { 16 | m_type = box_type_moov(); 17 | } 18 | 19 | std::string Moov::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Moov::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Moov::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/mvex.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/mvex.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_mvex() { 12 | return BoxType("mvex"); 13 | } 14 | 15 | Mvex::Mvex() { 16 | m_type = box_type_mvex(); 17 | } 18 | 19 | std::string Mvex::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Mvex::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Mvex::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/pixel_aspect_ratio.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/pixel_aspect_ratio.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_pasp() { 18 | return BoxType("pasp"); 19 | } 20 | 21 | PixelAspectRatio::PixelAspectRatio() { 22 | m_type = box_type_pasp(); 23 | } 24 | 25 | PixelAspectRatio::PixelAspectRatio(const PixelAspectRatioParameters& params) 26 | : m_h_spacing(params.h_spacing), m_v_spacing(params.v_spacing) { 27 | m_type = box_type_pasp(); 28 | } 29 | 30 | std::string PixelAspectRatio::toStringOnlyData() const { 31 | return fmt::format("HSpacing={} VSpacing={}", m_h_spacing, m_v_spacing); 32 | } 33 | 34 | std::uint64_t PixelAspectRatio::writeData(std::ostream& os) const { 35 | bitio::Writer writer(os); 36 | auto wbits = bitio::write_uint(&writer, m_h_spacing); 37 | return wbits + bitio::write_uint(&writer, m_v_spacing); 38 | } 39 | 40 | std::uint64_t PixelAspectRatio::readData(std::istream& is) { 41 | bitio::Reader reader(is); 42 | auto rbits = bitio::read_uint(&reader, &m_h_spacing); 43 | return rbits + bitio::read_uint(&reader, &m_v_spacing); 44 | } 45 | 46 | std::uint64_t PixelAspectRatio::getDataSize() const { 47 | return 8; 48 | } 49 | 50 | } // namespace shiguredo::mp4::box 51 | -------------------------------------------------------------------------------- /src/box/schi.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/schi.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_schi() { 12 | return BoxType("schi"); 13 | } 14 | 15 | Schi::Schi() { 16 | m_type = box_type_schi(); 17 | } 18 | 19 | std::string Schi::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Schi::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Schi::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/sinf.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/sinf.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_sinf() { 12 | return BoxType("sinf"); 13 | } 14 | 15 | Sinf::Sinf() { 16 | m_type = box_type_sinf(); 17 | } 18 | 19 | std::string Sinf::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Sinf::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Sinf::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/skip.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/skip.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "shiguredo/mp4/bitio/bitio.hpp" 13 | #include "shiguredo/mp4/bitio/reader.hpp" 14 | #include "shiguredo/mp4/bitio/writer.hpp" 15 | #include "shiguredo/mp4/box_type.hpp" 16 | #include "shiguredo/mp4/stream/stream.hpp" 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | BoxType box_type_skip() { 21 | return BoxType("skip"); 22 | } 23 | 24 | Skip::Skip() { 25 | m_type = box_type_skip(); 26 | } 27 | 28 | Skip::Skip(const SkipParameters& params) : m_data(params.data) { 29 | m_type = box_type_skip(); 30 | } 31 | 32 | std::string Skip::toStringOnlyData() const { 33 | return fmt::format("Data=[{:#x}]", fmt::join(m_data, ", ")); 34 | } 35 | 36 | std::uint64_t Skip::writeData(std::ostream& os) const { 37 | bitio::Writer writer(os); 38 | return bitio::write_vector_uint(&writer, m_data); 39 | } 40 | 41 | std::uint64_t Skip::readData(std::istream& is) { 42 | bitio::Reader reader(is); 43 | const std::size_t offset_to_end = static_cast(shiguredo::mp4::stream::get_istream_offset_to_end(is)); 44 | return bitio::read_vector_uint(&reader, offset_to_end, &m_data); 45 | } 46 | 47 | std::uint64_t Skip::getDataSize() const { 48 | return std::size(m_data); 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/smhd.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/smhd.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_smhd() { 18 | return BoxType("smhd"); 19 | } 20 | 21 | Smhd::Smhd() { 22 | m_type = box_type_smhd(); 23 | } 24 | 25 | Smhd::Smhd(const SmhdParameters& params) : m_balance(params.balance) { 26 | setVersion(params.version); 27 | setFlags(params.flags); 28 | m_type = box_type_smhd(); 29 | } 30 | 31 | std::string Smhd::toStringOnlyData() const { 32 | return fmt::format("{} Balance={:.2f}", getVersionAndFlagsString(), getBalance()); 33 | } 34 | 35 | std::uint64_t Smhd::writeData(std::ostream& os) const { 36 | bitio::Writer writer(os); 37 | const std::uint64_t wbits = writeVersionAndFlag(&writer); 38 | return wbits + bitio::write_uint(&writer, m_balance) + 39 | bitio::write_uint(&writer, m_reserved); 40 | } 41 | 42 | std::uint64_t Smhd::getDataSize() const { 43 | return 8; 44 | } 45 | 46 | std::uint64_t Smhd::readData(std::istream& is) { 47 | bitio::Reader reader(is); 48 | std::uint64_t rbits = readVersionAndFlag(&reader); 49 | return rbits + bitio::read_uint(&reader, &m_balance) + 50 | bitio::read_uint(&reader, &m_reserved); 51 | } 52 | 53 | float Smhd::getBalance() const { 54 | return static_cast(m_balance) / (1 << 8); 55 | } 56 | 57 | } // namespace shiguredo::mp4::box 58 | -------------------------------------------------------------------------------- /src/box/stbl.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/stbl.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_stbl() { 12 | return BoxType("stbl"); 13 | } 14 | 15 | Stbl::Stbl() { 16 | m_type = box_type_stbl(); 17 | } 18 | 19 | std::string Stbl::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Stbl::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Stbl::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/stco.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/stco.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "shiguredo/mp4/bitio/bitio.hpp" 13 | #include "shiguredo/mp4/bitio/reader.hpp" 14 | #include "shiguredo/mp4/bitio/writer.hpp" 15 | #include "shiguredo/mp4/box_type.hpp" 16 | 17 | namespace shiguredo::mp4::box { 18 | 19 | BoxType box_type_stco() { 20 | return BoxType("stco"); 21 | } 22 | 23 | Stco::Stco() { 24 | m_type = box_type_stco(); 25 | } 26 | 27 | Stco::Stco(const StcoParameters& params) : m_chunk_offsets(params.chunk_offsets) { 28 | setVersion(params.version); 29 | setFlags(params.flags); 30 | m_type = box_type_stco(); 31 | } 32 | 33 | std::string Stco::toStringOnlyData() const { 34 | return fmt::format("{} EntryCount={} ChunkOffsets=[{:#x}]", getVersionAndFlagsString(), std::size(m_chunk_offsets), 35 | fmt::join(m_chunk_offsets, ", ")); 36 | } 37 | 38 | std::uint64_t Stco::writeData(std::ostream& os) const { 39 | bitio::Writer writer(os); 40 | std::uint64_t wbits = writeVersionAndFlag(&writer); 41 | return wbits + bitio::write_uint(&writer, static_cast(std::size(m_chunk_offsets))) + 42 | bitio::write_vector_uint(&writer, m_chunk_offsets); 43 | } 44 | 45 | std::uint64_t Stco::readData(std::istream& is) { 46 | bitio::Reader reader(is); 47 | std::uint64_t rbits = readVersionAndFlag(&reader); 48 | std::uint32_t entry_count; 49 | rbits += bitio::read_uint(&reader, &entry_count); 50 | return rbits + bitio::read_vector_uint(&reader, entry_count, &m_chunk_offsets); 51 | } 52 | 53 | std::uint64_t Stco::getDataSize() const { 54 | return 8 + std::size(m_chunk_offsets) * 4; 55 | } 56 | 57 | std::ostream& operator<<(std::ostream& os, const Stco& stco) { 58 | os << stco.toString(); 59 | return os; 60 | } 61 | 62 | } // namespace shiguredo::mp4::box 63 | -------------------------------------------------------------------------------- /src/box/stsd.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/stsd.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_stsd() { 18 | return BoxType("stsd"); 19 | } 20 | 21 | Stsd::Stsd() { 22 | m_type = box_type_stsd(); 23 | } 24 | 25 | Stsd::Stsd(const StsdParameters& params) : m_entry_count(params.entry_count) { 26 | setVersion(params.version); 27 | setFlags(params.flags); 28 | m_type = box_type_stsd(); 29 | } 30 | 31 | std::string Stsd::toStringOnlyData() const { 32 | return fmt::format("{} EntryCount={}", getVersionAndFlagsString(), m_entry_count); 33 | } 34 | 35 | std::uint64_t Stsd::writeData(std::ostream& os) const { 36 | bitio::Writer writer(os); 37 | std::uint64_t wbits = writeVersionAndFlag(&writer); 38 | return wbits + bitio::write_uint(&writer, m_entry_count); 39 | } 40 | 41 | std::uint64_t Stsd::getDataSize() const { 42 | return 8; 43 | } 44 | 45 | std::uint64_t Stsd::readData(std::istream& is) { 46 | bitio::Reader reader(is); 47 | std::uint64_t rbits = readVersionAndFlag(&reader); 48 | return rbits + bitio::read_uint(&reader, &m_entry_count); 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/stss.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/stss.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "shiguredo/mp4/bitio/bitio.hpp" 13 | #include "shiguredo/mp4/bitio/reader.hpp" 14 | #include "shiguredo/mp4/bitio/writer.hpp" 15 | #include "shiguredo/mp4/box_type.hpp" 16 | 17 | namespace shiguredo::mp4::box { 18 | 19 | BoxType box_type_stss() { 20 | return BoxType("stss"); 21 | } 22 | 23 | Stss::Stss() { 24 | m_type = box_type_stss(); 25 | } 26 | 27 | Stss::Stss(const StssParmeters& params) : m_sample_numbers(params.sample_numbers) { 28 | setVersion(params.version); 29 | setFlags(params.flags); 30 | m_type = box_type_stss(); 31 | } 32 | 33 | std::string Stss::toStringOnlyData() const { 34 | return fmt::format("{} EntryCount={} SampleNumbers=[{}]", getVersionAndFlagsString(), std::size(m_sample_numbers), 35 | fmt::join(m_sample_numbers, ", ")); 36 | } 37 | 38 | std::uint64_t Stss::writeData(std::ostream& os) const { 39 | bitio::Writer writer(os); 40 | std::uint64_t wbits = writeVersionAndFlag(&writer); 41 | std::uint32_t entry_count = static_cast(std::size(m_sample_numbers)); 42 | return wbits += bitio::write_uint(&writer, entry_count) + 43 | bitio::write_vector_uint(&writer, m_sample_numbers); 44 | } 45 | 46 | std::uint64_t Stss::getDataSize() const { 47 | return 8 + std::size(m_sample_numbers) * 4; 48 | } 49 | 50 | std::uint64_t Stss::readData(std::istream& is) { 51 | bitio::Reader reader(is); 52 | std::uint64_t rbits = readVersionAndFlag(&reader); 53 | std::uint32_t entry_count; 54 | rbits += bitio::read_uint(&reader, &entry_count); 55 | return rbits += bitio::read_vector_uint(&reader, entry_count, &m_sample_numbers); 56 | } 57 | 58 | } // namespace shiguredo::mp4::box 59 | -------------------------------------------------------------------------------- /src/box/stsz.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/stsz.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "shiguredo/mp4/bitio/bitio.hpp" 13 | #include "shiguredo/mp4/bitio/reader.hpp" 14 | #include "shiguredo/mp4/bitio/writer.hpp" 15 | #include "shiguredo/mp4/box_type.hpp" 16 | 17 | namespace shiguredo::mp4::box { 18 | 19 | BoxType box_type_stsz() { 20 | return BoxType("stsz"); 21 | } 22 | 23 | Stsz::Stsz() { 24 | m_type = box_type_stsz(); 25 | } 26 | 27 | Stsz::Stsz(const StszParameters& params) : m_sample_size(params.sample_size), m_entry_sizes(params.entry_sizes) { 28 | setVersion(params.version); 29 | setFlags(params.flags); 30 | m_type = box_type_stsz(); 31 | } 32 | 33 | std::string Stsz::toStringOnlyData() const { 34 | return fmt::format("{} SampleSize={} SampleCount={} EntrySizes=[{}]", getVersionAndFlagsString(), m_sample_size, 35 | std::size(m_entry_sizes), fmt::join(m_entry_sizes, ", ")); 36 | } 37 | 38 | std::uint64_t Stsz::writeData(std::ostream& os) const { 39 | bitio::Writer writer(os); 40 | std::uint64_t wbits = writeVersionAndFlag(&writer); 41 | wbits += bitio::write_uint(&writer, m_sample_size); 42 | wbits += bitio::write_uint(&writer, static_cast(std::size(m_entry_sizes))); 43 | if (m_sample_size == 0) { 44 | wbits += bitio::write_vector_uint(&writer, m_entry_sizes); 45 | } 46 | return wbits; 47 | } 48 | 49 | std::uint64_t Stsz::getDataSize() const { 50 | return 12 + (m_sample_size == 0 ? 4 * std::size(m_entry_sizes) : 0); 51 | } 52 | 53 | std::uint64_t Stsz::readData(std::istream& is) { 54 | bitio::Reader reader(is); 55 | std::uint64_t rbits = readVersionAndFlag(&reader); 56 | rbits += bitio::read_uint(&reader, &m_sample_size); 57 | std::uint32_t sample_count; 58 | rbits += bitio::read_uint(&reader, &sample_count); 59 | if (m_sample_size == 0) { 60 | rbits += bitio::read_vector_uint(&reader, sample_count, &m_entry_sizes); 61 | } else { 62 | m_entry_sizes.clear(); 63 | } 64 | return rbits; 65 | } 66 | 67 | } // namespace shiguredo::mp4::box 68 | -------------------------------------------------------------------------------- /src/box/tfdt.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/tfdt.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_tfdt() { 18 | return BoxType("tfdt"); 19 | } 20 | 21 | Tfdt::Tfdt() { 22 | m_type = box_type_tfdt(); 23 | } 24 | 25 | Tfdt::Tfdt(const TfdtParameters& params) : m_base_media_decode_time(params.base_media_decode_time) { 26 | setVersion(params.version); 27 | setFlags(params.flags); 28 | m_type = box_type_tfdt(); 29 | } 30 | 31 | std::string Tfdt::toStringOnlyData() const { 32 | return fmt::format("{} BaseMediaDecodeTime={}", getVersionAndFlagsString(), m_base_media_decode_time); 33 | } 34 | 35 | std::uint64_t Tfdt::writeData(std::ostream& os) const { 36 | bitio::Writer writer(os); 37 | std::uint64_t wbits = writeVersionAndFlag(&writer); 38 | return wbits + bitio::write_uint(&writer, m_base_media_decode_time, m_version == 0 ? 32 : 64); 39 | } 40 | 41 | std::uint64_t Tfdt::getDataSize() const { 42 | return 8 + (m_version == 0 ? 0 : 4); 43 | } 44 | 45 | std::uint64_t Tfdt::readData(std::istream& is) { 46 | bitio::Reader reader(is); 47 | std::uint64_t rbits = readVersionAndFlag(&reader); 48 | return rbits + bitio::read_uint(&reader, &m_base_media_decode_time, m_version == 0 ? 32 : 64); 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/traf.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/traf.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_traf() { 12 | return BoxType("traf"); 13 | } 14 | 15 | Traf::Traf() { 16 | m_type = box_type_traf(); 17 | } 18 | 19 | std::string Traf::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Traf::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Traf::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/trak.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/trak.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_trak() { 12 | return BoxType("trak"); 13 | } 14 | 15 | Trak::Trak() { 16 | m_type = box_type_trak(); 17 | } 18 | 19 | std::string Trak::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Trak::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Trak::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/trex.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/trex.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | 15 | namespace shiguredo::mp4::box { 16 | 17 | BoxType box_type_trex() { 18 | return BoxType("trex"); 19 | } 20 | 21 | Trex::Trex() { 22 | m_type = box_type_trex(); 23 | } 24 | 25 | Trex::Trex(const TrexParameters& params) 26 | : m_track_id(params.track_id), 27 | m_default_sample_description_index(params.default_sample_description_index), 28 | m_default_sample_duration(params.default_sample_duration), 29 | m_default_sample_size(params.default_sample_size), 30 | m_default_sample_flags(params.default_sample_flags) { 31 | setVersion(params.version); 32 | setFlags(params.flags); 33 | m_type = box_type_trex(); 34 | } 35 | 36 | std::string Trex::toStringOnlyData() const { 37 | return fmt::format( 38 | "{} TrackID={} DefaultSampleDescriptionIndex={} DefaultSampleDuration={} DefaultSampleSize={} " 39 | "DefaultSampleFlags={:#x}", 40 | getVersionAndFlagsString(), m_track_id, m_default_sample_description_index, m_default_sample_duration, 41 | m_default_sample_size, m_default_sample_flags); 42 | } 43 | 44 | std::uint64_t Trex::writeData(std::ostream& os) const { 45 | bitio::Writer writer(os); 46 | std::uint64_t wbits = writeVersionAndFlag(&writer); 47 | wbits += bitio::write_uint(&writer, m_track_id); 48 | wbits += bitio::write_uint(&writer, m_default_sample_description_index); 49 | wbits += bitio::write_uint(&writer, m_default_sample_duration); 50 | wbits += bitio::write_uint(&writer, m_default_sample_size); 51 | wbits += bitio::write_uint(&writer, m_default_sample_flags); 52 | return wbits; 53 | } 54 | 55 | std::uint64_t Trex::getDataSize() const { 56 | return 24; 57 | } 58 | 59 | std::uint64_t Trex::readData(std::istream& is) { 60 | bitio::Reader reader(is); 61 | std::uint64_t rbits = readVersionAndFlag(&reader); 62 | rbits += bitio::read_uint(&reader, &m_track_id); 63 | rbits += bitio::read_uint(&reader, &m_default_sample_description_index); 64 | rbits += bitio::read_uint(&reader, &m_default_sample_duration); 65 | rbits += bitio::read_uint(&reader, &m_default_sample_size); 66 | rbits += bitio::read_uint(&reader, &m_default_sample_flags); 67 | return rbits; 68 | } 69 | 70 | } // namespace shiguredo::mp4::box 71 | -------------------------------------------------------------------------------- /src/box/udta.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/udta.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_udta() { 12 | return BoxType("udta"); 13 | } 14 | 15 | Udta::Udta() { 16 | m_type = box_type_udta(); 17 | } 18 | 19 | std::string Udta::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Udta::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Udta::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box/unsupported.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/unsupported.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "shiguredo/mp4/bitio/bitio.hpp" 13 | #include "shiguredo/mp4/bitio/reader.hpp" 14 | #include "shiguredo/mp4/bitio/writer.hpp" 15 | #include "shiguredo/mp4/box_type.hpp" 16 | #include "shiguredo/mp4/stream/stream.hpp" 17 | 18 | namespace shiguredo::mp4::box { 19 | 20 | BoxType box_type_unsupported() { 21 | return BoxType("unsu"); 22 | } 23 | 24 | Unsupported::Unsupported() { 25 | m_type = box_type_unsupported(); 26 | } 27 | 28 | Unsupported::Unsupported(const UnsupportedParameters& params) : m_data(params.data) { 29 | m_type = box_type_unsupported(); 30 | } 31 | 32 | std::string Unsupported::toStringOnlyData() const { 33 | return fmt::format("(unsupported) Data=[{:#x}]", fmt::join(m_data, ", ")); 34 | } 35 | 36 | std::uint64_t Unsupported::writeData(std::ostream& os) const { 37 | bitio::Writer writer(os); 38 | return bitio::write_vector_uint(&writer, m_data); 39 | } 40 | 41 | std::uint64_t Unsupported::readData(std::istream& is) { 42 | bitio::Reader reader(is); 43 | const std::size_t offset_to_end = static_cast(shiguredo::mp4::stream::get_istream_offset_to_end(is)); 44 | return bitio::read_vector_uint(&reader, offset_to_end, &m_data); 45 | } 46 | 47 | std::uint64_t Unsupported::getDataSize() const { 48 | return std::size(m_data); 49 | } 50 | 51 | } // namespace shiguredo::mp4::box 52 | -------------------------------------------------------------------------------- /src/box/url.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/url.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | #include "shiguredo/mp4/stream/stream.hpp" 15 | 16 | namespace shiguredo::mp4::box { 17 | 18 | BoxType box_type_url() { 19 | return BoxType("url "); 20 | } 21 | 22 | Url::Url() { 23 | m_type = box_type_url(); 24 | setFlags(UrlSelfContainedFlags); 25 | } 26 | 27 | Url::Url(const UrlParameters& params) : m_location(params.location) { 28 | setVersion(params.version); 29 | setFlags(params.flags); 30 | m_type = box_type_url(); 31 | } 32 | 33 | std::string Url::toStringOnlyData() const { 34 | if (checkFlag(UrlSelfContainedFlags)) { 35 | return getVersionAndFlagsString(); 36 | } 37 | return fmt::format("{} Location=\"{}\"", getVersionAndFlagsString(), m_location); 38 | } 39 | 40 | std::uint64_t Url::writeData(std::ostream& os) const { 41 | bitio::Writer writer(os); 42 | std::uint64_t wbits = writeVersionAndFlag(&writer); 43 | if (!checkFlag(UrlSelfContainedFlags)) { 44 | wbits += bitio::write_string(&writer, m_location); 45 | } 46 | return wbits; 47 | } 48 | 49 | std::uint64_t Url::readData(std::istream& is) { 50 | bitio::Reader reader(is); 51 | std::uint64_t rbits = readVersionAndFlag(&reader); 52 | if (!checkFlag(UrlSelfContainedFlags)) { 53 | const auto offset_to_end = static_cast(shiguredo::mp4::stream::get_istream_offset_to_end(is)); 54 | rbits += bitio::read_string(&reader, &m_location, offset_to_end * 8); 55 | } 56 | return rbits; 57 | } 58 | 59 | std::uint64_t Url::getDataSize() const { 60 | if (checkFlag(UrlSelfContainedFlags)) { 61 | return 4; 62 | } 63 | return 4 + std::size(m_location) + 1; 64 | } 65 | 66 | } // namespace shiguredo::mp4::box 67 | -------------------------------------------------------------------------------- /src/box/urn.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/urn.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | #include "shiguredo/mp4/bitio/writer.hpp" 13 | #include "shiguredo/mp4/box_type.hpp" 14 | #include "shiguredo/mp4/stream/stream.hpp" 15 | 16 | namespace shiguredo::mp4::box { 17 | 18 | BoxType box_type_urn() { 19 | return BoxType("urn "); 20 | } 21 | 22 | Urn::Urn() { 23 | m_type = box_type_urn(); 24 | setFlags(UrnSelfContainedFlags); 25 | } 26 | 27 | Urn::Urn(const UrnParameters& params) : m_name(params.name), m_location(params.location) { 28 | setVersion(params.version); 29 | setFlags(params.flags); 30 | m_type = box_type_urn(); 31 | } 32 | 33 | std::string Urn::toStringOnlyData() const { 34 | if (checkFlag(UrnSelfContainedFlags)) { 35 | return getVersionAndFlagsString(); 36 | } 37 | return fmt::format("{} Name=\"{}\" Location=\"{}\"", getVersionAndFlagsString(), m_name, m_location); 38 | } 39 | 40 | std::uint64_t Urn::writeData(std::ostream& os) const { 41 | bitio::Writer writer(os); 42 | std::uint64_t wbits = writeVersionAndFlag(&writer); 43 | if (checkFlag(UrnSelfContainedFlags)) { 44 | return wbits; 45 | } 46 | wbits += bitio::write_string(&writer, m_name); 47 | wbits += bitio::write_string(&writer, m_location); 48 | return wbits; 49 | } 50 | 51 | std::uint64_t Urn::readData(std::istream& is) { 52 | bitio::Reader reader(is); 53 | std::uint64_t rbits = readVersionAndFlag(&reader); 54 | if (checkFlag(UrnSelfContainedFlags)) { 55 | return rbits; 56 | } 57 | const auto offset_to_end = static_cast(shiguredo::mp4::stream::get_istream_offset_to_end(is)); 58 | const auto name_rbits = bitio::read_string(&reader, &m_name, (offset_to_end - 1) * 8); 59 | rbits += name_rbits; 60 | rbits += bitio::read_string(&reader, &m_location, offset_to_end * 8 - name_rbits); 61 | return rbits; 62 | } 63 | 64 | std::uint64_t Urn::getDataSize() const { 65 | if (checkFlag(UrnSelfContainedFlags)) { 66 | return 4; 67 | } 68 | return 4 + std::size(m_name) + 1 + std::size(m_location) + 1; 69 | } 70 | 71 | } // namespace shiguredo::mp4::box 72 | -------------------------------------------------------------------------------- /src/box/vmhd.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/vmhd.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "shiguredo/mp4/bitio/bitio.hpp" 12 | #include "shiguredo/mp4/bitio/reader.hpp" 13 | #include "shiguredo/mp4/bitio/writer.hpp" 14 | #include "shiguredo/mp4/box_type.hpp" 15 | 16 | namespace shiguredo::mp4::box { 17 | 18 | BoxType box_type_vmhd() { 19 | return BoxType("vmhd"); 20 | } 21 | 22 | Vmhd::Vmhd() { 23 | m_type = box_type_vmhd(); 24 | } 25 | 26 | Vmhd::Vmhd(const VmhdParameters& params) : m_graphicsmode(params.graphicsmode), m_opcolor(params.opcolor) { 27 | setVersion(params.version); 28 | setFlags(params.flags); 29 | m_type = box_type_vmhd(); 30 | } 31 | 32 | std::string Vmhd::toStringOnlyData() const { 33 | return fmt::format("{} Graphicsmode={} Opcolor=[{}]", getVersionAndFlagsString(), m_graphicsmode, 34 | fmt::join(m_opcolor, ", ")); 35 | } 36 | 37 | std::uint64_t Vmhd::writeData(std::ostream& os) const { 38 | bitio::Writer writer(os); 39 | std::uint64_t wbits = writeVersionAndFlag(&writer); 40 | wbits += bitio::write_uint(&writer, m_graphicsmode); 41 | for (const auto c : m_opcolor) { 42 | wbits += bitio::write_uint(&writer, c); 43 | } 44 | return wbits; 45 | } 46 | 47 | std::uint64_t Vmhd::getDataSize() const { 48 | return 12; 49 | } 50 | 51 | std::uint64_t Vmhd::readData(std::istream& is) { 52 | bitio::Reader reader(is); 53 | std::uint64_t rbits = readVersionAndFlag(&reader); 54 | rbits += bitio::read_uint(&reader, &m_graphicsmode); 55 | for (std::size_t i = 0; i < std::size(m_opcolor); ++i) { 56 | rbits += bitio::read_uint(&reader, &(m_opcolor[i])); 57 | } 58 | return rbits; 59 | } 60 | 61 | } // namespace shiguredo::mp4::box 62 | -------------------------------------------------------------------------------- /src/box/wave.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box/wave.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "shiguredo/mp4/box_type.hpp" 8 | 9 | namespace shiguredo::mp4::box { 10 | 11 | BoxType box_type_wave() { 12 | return BoxType("wave"); 13 | } 14 | 15 | Wave::Wave() { 16 | m_type = box_type_wave(); 17 | } 18 | 19 | std::string Wave::toStringOnlyData() const { 20 | return ""; 21 | } 22 | 23 | std::uint64_t Wave::writeData(std::ostream&) const { 24 | return 0; 25 | } 26 | 27 | std::uint64_t Wave::readData(std::istream&) { 28 | return 0; 29 | } 30 | 31 | } // namespace shiguredo::mp4::box 32 | -------------------------------------------------------------------------------- /src/box_info.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box_info.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "shiguredo/mp4/box.hpp" 12 | #include "shiguredo/mp4/box/sample_entry.hpp" 13 | 14 | namespace shiguredo::mp4 { 15 | 16 | BoxInfo::BoxInfo(const BoxInfoParameters& params) : m_box(params.box) { 17 | if (params.parent) { 18 | m_path = params.parent->getPath(); 19 | params.parent->addLeaf(this); 20 | if (params.parent->getType() == BoxType("wave")) { 21 | auto ase = dynamic_cast(m_box); 22 | if (ase) { 23 | spdlog::debug("BoxInfo::BoxInfo(): setUnderWave()"); 24 | ase->setUnderWave(true); 25 | } 26 | } 27 | } else { 28 | m_path = {}; 29 | } 30 | m_path.push_back(m_box->getType()); 31 | } 32 | 33 | BoxInfo::~BoxInfo() { 34 | for (BoxInfo* l : m_leafs) { 35 | delete l; 36 | } 37 | delete m_box; 38 | } 39 | 40 | BoxPath BoxInfo::getPath() const { 41 | return m_path; 42 | } 43 | 44 | Box* BoxInfo::getBox() const { 45 | return m_box; 46 | } 47 | 48 | std::uint64_t BoxInfo::getSize() const { 49 | return m_box->getSize(); 50 | } 51 | 52 | void BoxInfo::addLeaf(BoxInfo* info) { 53 | m_leafs.push_back(info); 54 | } 55 | 56 | std::string BoxInfo::toString() const { 57 | std::vector leafs; 58 | std::transform(std::begin(m_leafs), std::end(m_leafs), std::back_inserter(leafs), 59 | [](const BoxInfo* info) { return fmt::format("{}", info->toString()); }); 60 | const std::string pad((std::size(m_path) - 1) * 2, ' '); 61 | if (std::empty(leafs)) { 62 | return fmt::format("{}{}", pad, m_box->toString()); 63 | } 64 | return fmt::format("{}{}\n{}", pad, m_box->toString(), fmt::join(leafs, "\n")); 65 | } 66 | 67 | std::uint64_t BoxInfo::adjustOffsetAndSize(const std::uint64_t offset) { 68 | std::uint64_t leafs_size = 0; 69 | const std::uint64_t header_size = m_box->getHeaderSize(); 70 | const std::uint64_t data_size = m_box->getDataSize(); 71 | for (auto l : m_leafs) { 72 | leafs_size += l->adjustOffsetAndSize(offset + header_size + data_size + leafs_size); 73 | } 74 | 75 | m_box->setOffsetAndDataSize(offset, data_size + leafs_size); 76 | 77 | if (header_size != m_box->getHeaderSize()) { 78 | adjustOffsetAndSize(offset); 79 | } 80 | return m_box->getSize(); 81 | } 82 | 83 | void BoxInfo::write(std::ostream& os) const { 84 | spdlog::trace("BoxInfo::write(): {}", m_box->toString()); 85 | m_box->write(os); 86 | for (auto l : m_leafs) { 87 | l->write(os); 88 | } 89 | } 90 | 91 | BoxType BoxInfo::getType() const { 92 | return m_box->getType(); 93 | } 94 | 95 | } // namespace shiguredo::mp4 96 | -------------------------------------------------------------------------------- /src/box_map.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box_map.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "shiguredo/mp4/box.hpp" 15 | #include "shiguredo/mp4/box/unsupported.hpp" 16 | #include "shiguredo/mp4/box_header.hpp" 17 | 18 | namespace shiguredo::mp4 { 19 | 20 | BoxDef::BoxDef(const BoxDefParameters& params) : factory(params.factory), versions(params.versions) {} 21 | 22 | void BoxMap::addBoxDef(const BoxFactory& factory, const BoxType& box_type, const std::vector& versions) { 23 | m_map[box_type] = std::make_unique(BoxDefParameters{.factory = factory, .versions = versions}); 24 | } 25 | 26 | Box* BoxMap::getBoxInstance(const BoxType& type) { 27 | const auto it = m_map.find(type); 28 | Box* box; 29 | if (it == m_map.end()) { 30 | spdlog::debug("BoxMap::getBoxInstance(): box not found: {}", type.toString()); 31 | box = new box::Unsupported(); 32 | } else { 33 | box = it->second->factory(); 34 | auto any_type_box = dynamic_cast(box); 35 | if (any_type_box != nullptr) { 36 | any_type_box->setType(type); 37 | } 38 | } 39 | 40 | return box; 41 | } 42 | 43 | Box* BoxMap::getBoxInstance(BoxHeader* header) { 44 | Box* box = getBoxInstance(header->getType()); 45 | box->setHeader(header); 46 | return box; 47 | } 48 | 49 | bool BoxMap::isSupported(const BoxType& box_type) const { 50 | return m_map.contains(box_type); 51 | } 52 | 53 | std::vector BoxMap::getSupportedVersions(const BoxType& box_type) const { 54 | const auto it = m_map.find(box_type); 55 | if (it == std::end(m_map)) { 56 | throw std::runtime_error("BoxMap::getSupportedVersions(): not found"); 57 | } 58 | return it->second->versions; 59 | } 60 | 61 | bool BoxMap::isSupportedVersion(const BoxType& box_type, const std::uint8_t ver) const { 62 | const auto it = m_map.find(box_type); 63 | if (it == std::end(m_map)) { 64 | return false; 65 | } 66 | auto vs = it->second->versions; 67 | if (std::empty(vs)) { 68 | return true; 69 | } 70 | return std::any_of(std::begin(vs), std::end(vs), [ver](const auto v) { return ver == v; }); 71 | } 72 | 73 | } // namespace shiguredo::mp4 74 | -------------------------------------------------------------------------------- /src/box_type.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/box_type.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace shiguredo::mp4 { 17 | 18 | BoxType::BoxType(const std::string& str) { 19 | if (std::size(str) != 4) { 20 | throw std::invalid_argument(fmt::format("BoxType::BoxType(): invalid box type id length: [{}]", str)); 21 | } 22 | m_data[0] = static_cast(str[0]); 23 | m_data[1] = static_cast(str[1]); 24 | m_data[2] = static_cast(str[2]); 25 | m_data[3] = static_cast(str[3]); 26 | } 27 | 28 | BoxType::BoxType(const std::array& t_data) : m_data(t_data) {} 29 | 30 | void BoxType::setData(const std::uint8_t d0, const std::uint8_t d1, const std::uint8_t d2, const std::uint8_t d3) { 31 | m_data[0] = d0; 32 | m_data[1] = d1; 33 | m_data[2] = d2; 34 | m_data[3] = d3; 35 | } 36 | 37 | std::array BoxType::getData() const { 38 | return m_data; 39 | } 40 | 41 | std::string BoxType::toString() const { 42 | if (std::all_of(std::begin(m_data), std::end(m_data), 43 | [](const std::uint8_t ch) { return std::isprint(ch) != 0 || ch == 0xa9; })) { 44 | auto s = std::string(std::begin(m_data), std::end(m_data)); 45 | return std::regex_replace(s, std::regex("\x00a9"), "©"); 46 | } 47 | return fmt::format("0x{:02x}{:02x}{:02x}{:02x}", m_data[0], m_data[1], m_data[2], m_data[3]); 48 | } 49 | 50 | bool BoxType::matchWith(const BoxType& other) const { 51 | const auto boxTypeAny = box_type_any(); 52 | if (*this == boxTypeAny || other == boxTypeAny) { 53 | return true; 54 | } 55 | return *this == other; 56 | } 57 | 58 | BoxType box_type_any() { 59 | static BoxType boxTypeAny(std::array{0x00, 0x00, 0x00, 0x00}); 60 | return boxTypeAny; 61 | } 62 | 63 | } // namespace shiguredo::mp4 64 | -------------------------------------------------------------------------------- /src/cli/mp4-tool.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "shiguredo/mp4//reader/reader.hpp" 16 | 17 | int main(int argc, char** argv) { 18 | CLI::App app{"mp4-tool"}; 19 | 20 | spdlog::level::level_enum log_level = spdlog::level::info; 21 | std::vector> log_level_assoc{ 22 | {"trace", spdlog::level::trace}, {"debug", spdlog::level::debug}, {"info", spdlog::level::info}, 23 | {"warn", spdlog::level::warn}, {"error", spdlog::level::err}, {"critical", spdlog::level::critical}, 24 | {"off", spdlog::level::off}, 25 | }; 26 | app.add_option("-l,--log-level", log_level, "Log level (trace/debug/info/warn/error/critical/off) default: info") 27 | ->transform(CLI::CheckedTransformer(log_level_assoc, CLI::ignore_case)); 28 | 29 | app.require_subcommand(1); 30 | 31 | std::string filename; 32 | 33 | auto dump = app.add_subcommand("dump"); 34 | dump->add_option("-f,--file", filename, "filename"); 35 | 36 | CLI11_PARSE(app, argc, argv); 37 | 38 | spdlog::set_level(log_level); 39 | spdlog::set_default_logger(spdlog::stderr_color_mt("mp4-tool")); 40 | 41 | auto subcommands = app.get_subcommands(); 42 | 43 | if (subcommands[0] == dump) { 44 | std::ifstream ifs(filename, std::ios_base::binary); 45 | shiguredo::mp4::reader::SimpleReader reader(ifs); 46 | reader.read(); 47 | } 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /src/endian/endian.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/endian/endian.hpp" 2 | 3 | #include 4 | #include 5 | 6 | namespace shiguredo::mp4::endian { 7 | 8 | std::uint32_t be_to_uint32(const std::uint8_t d0, const std::uint8_t d1, const std::uint8_t d2, const std::uint8_t d3) { 9 | return (static_cast(d0) << 24) + (static_cast(d1) << 16) + 10 | (static_cast(d2) << 8) + (static_cast(d3)); 11 | } 12 | 13 | std::uint32_t be_to_uint32(const std::array& a) { 14 | return be_to_uint32(a[0], a[1], a[2], a[3]); 15 | } 16 | 17 | std::uint64_t be_to_uint64(const std::uint8_t d0, 18 | const std::uint8_t d1, 19 | const std::uint8_t d2, 20 | const std::uint8_t d3, 21 | const std::uint8_t d4, 22 | const std::uint8_t d5, 23 | const std::uint8_t d6, 24 | const std::uint8_t d7) { 25 | return (static_cast(d0) << 56) + (static_cast(d1) << 48) + 26 | (static_cast(d2) << 40) + (static_cast(d3) << 32) + 27 | (static_cast(d4) << 24) + (static_cast(d5) << 16) + 28 | (static_cast(d6) << 8) + (static_cast(d7)); 29 | } 30 | 31 | std::uint64_t be_to_uint64(const std::array& a) { 32 | return be_to_uint64(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); 33 | } 34 | 35 | std::array uint32_to_be(const std::uint32_t i) { 36 | return std::array{static_cast((i >> 24) & 0xff), 37 | static_cast((i >> 16) & 0xff), 38 | static_cast((i >> 8) & 0xff), static_cast((i)&0xff)}; 39 | } 40 | 41 | std::array uint64_to_be(const std::uint64_t i) { 42 | return std::array{ 43 | static_cast((i >> 56) & 0xff), static_cast((i >> 48) & 0xff), 44 | static_cast((i >> 40) & 0xff), static_cast((i >> 32) & 0xff), 45 | static_cast((i >> 24) & 0xff), static_cast((i >> 16) & 0xff), 46 | static_cast((i >> 8) & 0xff), static_cast((i)&0xff)}; 47 | } 48 | 49 | } // namespace shiguredo::mp4::endian 50 | -------------------------------------------------------------------------------- /src/stream/stream.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/stream/stream.hpp" 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace shiguredo::mp4::stream { 8 | 9 | std::streamoff get_istream_offset_to_end(std::istream& is) { 10 | const auto offset = is.tellg(); 11 | if (!is.good()) { 12 | throw std::runtime_error( 13 | fmt::format("stream::get_istream_offset_to_end(): istream::tellg() failed: rdstate={}", is.rdstate())); 14 | } 15 | is.seekg(0, std::ios_base::end); 16 | if (!is.good()) { 17 | throw std::runtime_error( 18 | fmt::format("stream::get_istream_offset_to_end(): istream::seekg() failed: rdstate={}", is.rdstate())); 19 | } 20 | const auto end_offset = is.tellg(); 21 | if (!is.good()) { 22 | throw std::runtime_error( 23 | fmt::format("stream::get_istream_offset_to_end(): istream::tellg() failed: rdstate={}", is.rdstate())); 24 | } 25 | is.seekg(offset, std::ios_base::beg); 26 | if (!is.good()) { 27 | throw std::runtime_error( 28 | fmt::format("stream::get_istream_offset_to_end(): istream::seekg() failed: rdstate={}", is.rdstate())); 29 | } 30 | return end_offset - offset; 31 | } 32 | 33 | } // namespace shiguredo::mp4::stream 34 | -------------------------------------------------------------------------------- /src/time/time.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/time/time.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace shiguredo::mp4::time { 11 | 12 | std::string format_epoch_19040101(const std::uint64_t t) { 13 | std::time_t from1970 = static_cast(t - SECONDS_19040101_to_19700101); 14 | if (from1970 > std::numeric_limits::max()) { 15 | // cannot handle big values. 16 | return "0000-00-00T00:00:00Z"; 17 | } 18 | std::tm tm; 19 | 20 | return fmt::format("{:%FT%TZ}", *gmtime_r(&from1970, &tm)); 21 | } 22 | 23 | std::uint64_t convert_to_epoch_19040101(const std::uint64_t t) { 24 | return t + SECONDS_19040101_to_19700101; 25 | } 26 | 27 | } // namespace shiguredo::mp4::time 28 | -------------------------------------------------------------------------------- /src/track/soun.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/track/soun.hpp" 2 | 3 | #include "shiguredo/mp4/box/boxes.hpp" 4 | #include "shiguredo/mp4/box_info.hpp" 5 | 6 | namespace shiguredo::mp4::track { 7 | 8 | SounTrack::SounTrack() { 9 | m_handler_type = HandlerType::soun; 10 | } 11 | 12 | void SounTrack::makeTkhdBoxInfo(BoxInfo* trak) { 13 | new BoxInfo({.parent = trak, 14 | .box = new box::Tkhd({.flags = 0x000003, 15 | .creation_time = m_time_from_epoch, 16 | .modification_time = m_time_from_epoch, 17 | .track_id = m_track_id, 18 | .duration = getDurationInMvhdTimescale()})}); 19 | } 20 | 21 | void SounTrack::makeSmhdBoxInfo(BoxInfo* minf) { 22 | new BoxInfo({.parent = minf, .box = new box::Smhd({.balance = 0})}); 23 | } 24 | 25 | } // namespace shiguredo::mp4::track 26 | -------------------------------------------------------------------------------- /src/track/vide.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/track/vide.hpp" 2 | 3 | #include "shiguredo/mp4/box/boxes.hpp" 4 | #include "shiguredo/mp4/box_info.hpp" 5 | 6 | namespace shiguredo::mp4::track { 7 | 8 | VideTrack::VideTrack() { 9 | m_handler_type = HandlerType::vide; 10 | } 11 | 12 | void VideTrack::makeTkhdBoxInfo(BoxInfo* trak) { 13 | new BoxInfo({.parent = trak, 14 | .box = new box::Tkhd({ 15 | .flags = 0x000003, 16 | .creation_time = m_time_from_epoch, 17 | .modification_time = m_time_from_epoch, 18 | .track_id = m_track_id, 19 | .duration = getDurationInMvhdTimescale(), 20 | .volume = 0, 21 | .width = m_width << 16, 22 | .height = m_height << 16, 23 | })}); 24 | } 25 | 26 | void VideTrack::makeVmhdBoxInfo(BoxInfo* minf) { 27 | new BoxInfo({.parent = minf, .box = new box::Vmhd({.flags = 0x000001})}); 28 | } 29 | 30 | } // namespace shiguredo::mp4::track 31 | -------------------------------------------------------------------------------- /src/version.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "shiguredo/mp4/constants.hpp" 6 | #include "shiguredo/mp4/version.hpp" 7 | 8 | namespace shiguredo::mp4 { 9 | 10 | std::string get_version_string() { 11 | return "2023.2.1"; 12 | } 13 | 14 | } // namespace shiguredo::mp4 15 | -------------------------------------------------------------------------------- /src/writer/writer.cpp: -------------------------------------------------------------------------------- 1 | #include "shiguredo/mp4/writer/writer.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "shiguredo/mp4/box/boxes.hpp" 9 | #include "shiguredo/mp4/box_info.hpp" 10 | #include "shiguredo/mp4/box_type.hpp" 11 | 12 | namespace shiguredo::mp4::writer { 13 | 14 | Writer::~Writer() { 15 | if (m_moov_box_info) { 16 | delete m_moov_box_info; 17 | } 18 | } 19 | 20 | void Writer::addMdatData(const std::vector& data) { 21 | addMdatData(data.data(), std::size(data)); 22 | } 23 | 24 | BoxInfo* Writer::getMoovBoxInfo() const { 25 | return m_moov_box_info; 26 | } 27 | 28 | std::uint64_t Writer::getTimeFromEpoch() const { 29 | return m_time_from_epoch; 30 | } 31 | 32 | std::uint32_t Writer::getMvhdTimescale() const { 33 | return m_mvhd_timescale; 34 | } 35 | 36 | std::uint32_t Writer::getAndUpdateNextTrackID() { 37 | const auto track_id = m_next_track_id; 38 | ++m_next_track_id; 39 | return track_id; 40 | } 41 | 42 | void Writer::appendUdtaBoxInfo(const box::DataParameters& data_params) { 43 | auto udta = new BoxInfo({.parent = m_moov_box_info, .box = new box::Udta()}); 44 | auto meta = new BoxInfo({.parent = udta, .box = new box::Meta()}); 45 | new BoxInfo({.parent = meta, .box = new box::Hdlr({.handler_type = {'m', 'd', 'i', 'r'}, .name = ""})}); 46 | auto ilst = new BoxInfo({.parent = meta, .box = new box::Ilst()}); 47 | auto ctoo = 48 | new BoxInfo({.parent = ilst, 49 | .box = new box::IlstMeta({.type = BoxType(std::array({0xa9, 't', 'o', 'o'}))})}); 50 | new BoxInfo({.parent = ctoo, .box = new box::Data(data_params)}); 51 | } 52 | 53 | } // namespace shiguredo::mp4::writer 54 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | add_subdirectory(bitio) 4 | add_subdirectory(endian) 5 | add_subdirectory(time) 6 | add_subdirectory(track) 7 | 8 | add_compile_options( 9 | -Wall 10 | -Wextra 11 | -Wshadow 12 | -Wnon-virtual-dtor 13 | -Wunused 14 | -Wold-style-cast 15 | -Wcast-align 16 | -Woverloaded-virtual 17 | -Wconversion 18 | -Wsign-conversion 19 | -Wmisleading-indentation 20 | -pedantic) 21 | 22 | add_executable(mp4_test 23 | main.cpp 24 | box_info.cpp 25 | box_header.cpp 26 | box_type.cpp 27 | box_types.cpp 28 | version.cpp 29 | ) 30 | 31 | set_target_properties(mp4_test PROPERTIES CXX_STANDARD 20 C_STANDARD 11) 32 | 33 | target_include_directories(mp4_test PRIVATE ../include) 34 | target_include_directories(mp4_test 35 | SYSTEM PRIVATE 36 | ${boost_algorithm_SOURCE_DIR}/include 37 | ${boost_assert_SOURCE_DIR}/include 38 | ${boost_bind_SOURCE_DIR}/include 39 | ${boost_config_SOURCE_DIR}/include 40 | ${boost_container_hash_SOURCE_DIR}/include 41 | ${boost_core_SOURCE_DIR}/include 42 | ${boost_describe_SOURCE_DIR}/include 43 | ${boost_detail_SOURCE_DIR}/include 44 | ${boost_exception_SOURCE_DIR}/include 45 | ${boost_function_SOURCE_DIR}/include 46 | ${boost_functional_SOURCE_DIR}/include 47 | ${boost_integer_SOURCE_DIR}/include 48 | ${boost_io_SOURCE_DIR}/include 49 | ${boost_iterator_SOURCE_DIR}/include 50 | ${boost_move_SOURCE_DIR}/include 51 | ${boost_mp11_SOURCE_DIR}/include 52 | ${boost_mpl_SOURCE_DIR}/include 53 | ${boost_numeric_conversion_SOURCE_DIR}/include 54 | ${boost_preprocessor_SOURCE_DIR}/include 55 | ${boost_range_SOURCE_DIR}/include 56 | ${boost_smart_ptr_SOURCE_DIR}/include 57 | ${boost_static_assert_SOURCE_DIR}/include 58 | ${boost_test_SOURCE_DIR}/include 59 | ${boost_throw_exception_SOURCE_DIR}/include 60 | ${boost_type_index_SOURCE_DIR}/include 61 | ${boost_type_traits_SOURCE_DIR}/include 62 | ${boost_utility_SOURCE_DIR}/include 63 | ${fmt_SOURCE_DIR}/include 64 | ${spdlog_SOURCE_DIR}/include 65 | ) 66 | 67 | target_link_libraries(mp4_test 68 | PRIVATE 69 | fmt 70 | spdlog 71 | shiguredo-mp4 72 | ) 73 | 74 | add_test(NAME mp4 COMMAND mp4_test) 75 | -------------------------------------------------------------------------------- /test/bitio/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | add_compile_options( 4 | -Wall 5 | -Wextra 6 | -Wshadow 7 | -Wnon-virtual-dtor 8 | -Wunused 9 | -Wold-style-cast 10 | -Wcast-align 11 | -Woverloaded-virtual 12 | -Wconversion 13 | -Wsign-conversion 14 | -Wmisleading-indentation 15 | -pedantic) 16 | 17 | add_executable(bitio_test 18 | main.cpp 19 | bitio.cpp 20 | reader.cpp 21 | writer.cpp 22 | ../../src/bitio/bitio.cpp 23 | ../../src/bitio/reader.cpp 24 | ../../src/bitio/writer.cpp 25 | ) 26 | 27 | set_target_properties(bitio_test PROPERTIES CXX_STANDARD 20 C_STANDARD 11) 28 | 29 | target_include_directories(bitio_test PRIVATE ../../include) 30 | target_include_directories(bitio_test 31 | SYSTEM PRIVATE 32 | ${boost_algorithm_SOURCE_DIR}/include 33 | ${boost_assert_SOURCE_DIR}/include 34 | ${boost_bind_SOURCE_DIR}/include 35 | ${boost_config_SOURCE_DIR}/include 36 | ${boost_container_hash_SOURCE_DIR}/include 37 | ${boost_core_SOURCE_DIR}/include 38 | ${boost_describe_SOURCE_DIR}/include 39 | ${boost_detail_SOURCE_DIR}/include 40 | ${boost_exception_SOURCE_DIR}/include 41 | ${boost_function_SOURCE_DIR}/include 42 | ${boost_integer_SOURCE_DIR}/include 43 | ${boost_io_SOURCE_DIR}/include 44 | ${boost_iterator_SOURCE_DIR}/include 45 | ${boost_move_SOURCE_DIR}/include 46 | ${boost_mp11_SOURCE_DIR}/include 47 | ${boost_mpl_SOURCE_DIR}/include 48 | ${boost_numeric_conversion_SOURCE_DIR}/include 49 | ${boost_preprocessor_SOURCE_DIR}/include 50 | ${boost_range_SOURCE_DIR}/include 51 | ${boost_smart_ptr_SOURCE_DIR}/include 52 | ${boost_static_assert_SOURCE_DIR}/include 53 | ${boost_test_SOURCE_DIR}/include 54 | ${boost_throw_exception_SOURCE_DIR}/include 55 | ${boost_type_index_SOURCE_DIR}/include 56 | ${boost_type_traits_SOURCE_DIR}/include 57 | ${boost_utility_SOURCE_DIR}/include 58 | ${fmt_SOURCE_DIR}/include 59 | ) 60 | 61 | target_link_libraries(bitio_test 62 | PRIVATE 63 | fmt 64 | ) 65 | 66 | add_test(NAME bitio COMMAND bitio_test) 67 | -------------------------------------------------------------------------------- /test/bitio/bitio.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "shiguredo/mp4/bitio/bitio.hpp" 11 | #include "shiguredo/mp4/bitio/reader.hpp" 12 | 13 | BOOST_AUTO_TEST_SUITE(marshal) 14 | 15 | struct UnmarshalPascalStringTestCase { 16 | const std::string name; 17 | const std::vector bin; 18 | const std::string str; 19 | }; 20 | 21 | UnmarshalPascalStringTestCase unmarshal_pascal_string_test_cases[] = { 22 | { 23 | "NormalString", 24 | {'s', 'h', 'i', 'g', 'u', 'r', 'e', 'd', 'o', 0}, 25 | "shiguredo", 26 | }, 27 | { 28 | "EmptyString", 29 | {}, 30 | "", 31 | }, 32 | { 33 | "AppleQuickTimePascalStringWithEmpty", 34 | {0x00}, 35 | "", 36 | }, 37 | { 38 | "AppleQuickTimePascalString", 39 | {9, 's', 'h', 'i', 'g', 'u', 'r', 'e', 'd', 'o'}, 40 | "shiguredo", 41 | }, 42 | { 43 | "AppleQuickTimePascalStringLong", 44 | {' ', 'a', ' ', '1', 's', 't', ' ', 'b', 'y', 't', 'e', ' ', 'e', 'q', 'u', 'a', 'l', 45 | 's', ' ', 't', 'o', ' ', 't', 'h', 'i', 's', ' ', 'l', 'e', 'n', 'g', 't', 'h'}, 46 | "a 1st byte equals to this length", 47 | }, 48 | }; 49 | 50 | BOOST_AUTO_TEST_CASE(unmarshal_pascal_string) { 51 | for (const auto& tc : unmarshal_pascal_string_test_cases) { 52 | BOOST_TEST_MESSAGE(tc.name); 53 | std::stringstream ss; 54 | std::copy(std::begin(tc.bin), std::end(tc.bin), std::ostreambuf_iterator(ss)); 55 | shiguredo::mp4::bitio::Reader reader(ss); 56 | 57 | std::string s; 58 | shiguredo::mp4::bitio::read_pascal_string(&reader, &s, std::size(tc.bin) * 8); 59 | BOOST_REQUIRE_EQUAL(tc.str, s); 60 | } 61 | } 62 | 63 | BOOST_AUTO_TEST_SUITE_END() 64 | -------------------------------------------------------------------------------- /test/bitio/main.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE "shiguredo::mp4::bitio test" 2 | #include 3 | -------------------------------------------------------------------------------- /test/bitio/writer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "shiguredo/mp4/bitio/writer.hpp" 10 | 11 | BOOST_AUTO_TEST_SUITE(writer) 12 | 13 | BOOST_AUTO_TEST_CASE(writer_basic) { 14 | std::stringstream ss; 15 | shiguredo::mp4::bitio::Writer writer(ss); 16 | 17 | // 1101,1010 18 | // ^^^ ^^^^ 19 | writer.writeBits({0xda}, 7); 20 | 21 | // 0000,0111,0110,0011,1101,0101 22 | // ^ ^^^^ ^^^^ ^^^^ ^^^^ 23 | writer.writeBits({0x07, 0x63, 0xd5}, 17); 24 | 25 | const auto ret = writer.write({0xa4, 0x6f}); 26 | BOOST_REQUIRE_EQUAL(2, ret); 27 | 28 | // 0000,0111,0110,1001,1110,0011 29 | // ^ ^^^^ ^^^^ ^^^^ ^^^^ 30 | writer.writeBits({0x07, 0x69, 0xe3}, 17); 31 | 32 | writer.writeBit(true); 33 | writer.writeBit(false); 34 | 35 | // 1111,0111 36 | // ^ ^^^^ 37 | writer.writeBits({0xf7}, 5); 38 | 39 | const std::uint8_t expected[] = { 40 | 0xb5, 0x63, 0xd5, // 1011,0101,0110,0011,1101,0101 41 | 0xa4, 0x6f, // 42 | 0xb4, 0xf1, 0xd7, // 1011,0100,1111,0001,1101,0111 43 | }; 44 | 45 | const auto s = ss.str(); 46 | const std::vector actual(std::begin(s), std::end(s)); 47 | BOOST_REQUIRE_EQUAL(8, std::size(actual)); 48 | 49 | BOOST_REQUIRE_EQUAL_COLLECTIONS(expected, expected + 8, actual.data(), actual.data() + std::size(actual)); 50 | } 51 | 52 | BOOST_AUTO_TEST_SUITE_END() 53 | -------------------------------------------------------------------------------- /test/box_info.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "shiguredo/mp4/box/boxes.hpp" 4 | #include "shiguredo/mp4/box_info.hpp" 5 | 6 | BOOST_AUTO_TEST_SUITE(box_info) 7 | 8 | BOOST_AUTO_TEST_CASE(box_info_tree) { 9 | auto moov = new shiguredo::mp4::BoxInfo({.box = new shiguredo::mp4::box::Moov()}); 10 | 11 | new shiguredo::mp4::BoxInfo( 12 | {.parent = moov, 13 | .box = new shiguredo::mp4::box::Mvhd( 14 | {.creation_time = 0, .modification_time = 0, .timescale = 1000, .duration = 15000, .next_track_id = 2})}); 15 | moov->adjustOffsetAndSize(100); 16 | BOOST_REQUIRE_EQUAL(R"([moov] Offset=100 Size=116 17 | [mvhd] Offset=108 Size=108 Version=0 Flags=0x000000 CreationTime="1904-01-01T00:00:00Z" ModificationTime="1904-01-01T00:00:00Z" Timescale=1000 Duration=15000 Rate=1.0000 Volume=256 Matrix=[0x10000, 0x0, 0x0, 0x0, 0x10000, 0x0, 0x0, 0x0, 0x40000000] PreDefined=[0, 0, 0, 0, 0, 0] NextTrackID=2)", 18 | moov->toString()); 19 | 20 | delete moov; 21 | } 22 | 23 | BOOST_AUTO_TEST_SUITE_END() 24 | -------------------------------------------------------------------------------- /test/box_type.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "shiguredo/mp4/box_type.hpp" 7 | 8 | BOOST_AUTO_TEST_SUITE(box_type) 9 | 10 | BOOST_AUTO_TEST_CASE(box_type_to_string) { 11 | BOOST_REQUIRE_EQUAL("1234", shiguredo::mp4::BoxType(std::array{'1', '2', '3', '4'}).toString()); 12 | BOOST_REQUIRE_EQUAL("abcd", shiguredo::mp4::BoxType(std::array{'a', 'b', 'c', 'd'}).toString()); 13 | BOOST_REQUIRE_EQUAL("xx x", shiguredo::mp4::BoxType(std::array{'x', 'x', ' ', 'x'}).toString()); 14 | BOOST_REQUIRE_EQUAL("xx-x", shiguredo::mp4::BoxType(std::array{'x', 'x', '-', 'x'}).toString()); 15 | BOOST_REQUIRE_EQUAL("xx©x", shiguredo::mp4::BoxType(std::array{'x', 'x', 0xa9, 'x'}).toString()); 16 | BOOST_REQUIRE_EQUAL("0x7878ab78", 17 | shiguredo::mp4::BoxType(std::array{'x', 'x', 0xab, 'x'}).toString()); 18 | } 19 | 20 | BOOST_AUTO_TEST_SUITE_END() 21 | -------------------------------------------------------------------------------- /test/endian/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | add_compile_options( 4 | -Wall 5 | -Wextra 6 | -Wshadow 7 | -Wnon-virtual-dtor 8 | -Wunused 9 | -Wold-style-cast 10 | -Wcast-align 11 | -Woverloaded-virtual 12 | -Wconversion 13 | -Wsign-conversion 14 | -Wmisleading-indentation 15 | -pedantic) 16 | 17 | add_executable(endian_test 18 | main.cpp 19 | endian.cpp 20 | ../../src/endian/endian.cpp 21 | ) 22 | 23 | set_target_properties(endian_test PROPERTIES CXX_STANDARD 20 C_STANDARD 11) 24 | 25 | target_include_directories(endian_test PRIVATE ../../include) 26 | target_include_directories(endian_test 27 | SYSTEM PRIVATE 28 | ${boost_algorithm_SOURCE_DIR}/include 29 | ${boost_assert_SOURCE_DIR}/include 30 | ${boost_bind_SOURCE_DIR}/include 31 | ${boost_config_SOURCE_DIR}/include 32 | ${boost_container_hash_SOURCE_DIR}/include 33 | ${boost_core_SOURCE_DIR}/include 34 | ${boost_describe_SOURCE_DIR}/include 35 | ${boost_detail_SOURCE_DIR}/include 36 | ${boost_exception_SOURCE_DIR}/include 37 | ${boost_function_SOURCE_DIR}/include 38 | ${boost_integer_SOURCE_DIR}/include 39 | ${boost_io_SOURCE_DIR}/include 40 | ${boost_iterator_SOURCE_DIR}/include 41 | ${boost_move_SOURCE_DIR}/include 42 | ${boost_mp11_SOURCE_DIR}/include 43 | ${boost_mpl_SOURCE_DIR}/include 44 | ${boost_numeric_conversion_SOURCE_DIR}/include 45 | ${boost_preprocessor_SOURCE_DIR}/include 46 | ${boost_range_SOURCE_DIR}/include 47 | ${boost_smart_ptr_SOURCE_DIR}/include 48 | ${boost_static_assert_SOURCE_DIR}/include 49 | ${boost_test_SOURCE_DIR}/include 50 | ${boost_throw_exception_SOURCE_DIR}/include 51 | ${boost_type_index_SOURCE_DIR}/include 52 | ${boost_type_traits_SOURCE_DIR}/include 53 | ${boost_utility_SOURCE_DIR}/include 54 | ) 55 | 56 | add_test(NAME endian COMMAND endian_test) 57 | -------------------------------------------------------------------------------- /test/endian/endian.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include "shiguredo/mp4/endian/endian.hpp" 8 | 9 | BOOST_AUTO_TEST_SUITE(endian) 10 | 11 | struct Uint32TestCase { 12 | const std::uint32_t number; 13 | const std::array array; 14 | }; 15 | 16 | Uint32TestCase uint32_test_cases[] = { 17 | {0, {0x00, 0x00, 0x00, 0x00}}, 18 | {0x12345678, {0x12, 0x34, 0x56, 0x78}}, 19 | {0x123456, {0x00, 0x12, 0x34, 0x56}}, 20 | {0xffffffff, {0xff, 0xff, 0xff, 0xff}}, 21 | }; 22 | 23 | BOOST_AUTO_TEST_CASE(uint32) { 24 | BOOST_TEST_MESSAGE("uint32"); 25 | for (const auto& tc : uint32_test_cases) { 26 | const auto array = shiguredo::mp4::endian::uint32_to_be(tc.number); 27 | BOOST_REQUIRE_EQUAL_COLLECTIONS(std::begin(tc.array), std::end(tc.array), std::begin(array), std::end(array)); 28 | const auto number = shiguredo::mp4::endian::be_to_uint32(array); 29 | BOOST_REQUIRE_EQUAL(tc.number, number); 30 | const auto number2 = shiguredo::mp4::endian::be_to_uint32(array[0], array[1], array[2], array[3]); 31 | BOOST_REQUIRE_EQUAL(tc.number, number2); 32 | } 33 | } 34 | 35 | struct Uint64TestCase { 36 | const std::uint64_t number; 37 | const std::array array; 38 | }; 39 | 40 | Uint64TestCase uint64_test_cases[] = { 41 | {0, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 42 | {0x123456789abcdef0, {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}}, 43 | {0x123456789abcdef, {0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}}, 44 | {0x123456789abcde, {0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde}}, 45 | {0xffffffffffffffff, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, 46 | }; 47 | 48 | BOOST_AUTO_TEST_CASE(uint64) { 49 | BOOST_TEST_MESSAGE("uint64"); 50 | for (const auto& tc : uint64_test_cases) { 51 | const auto array = shiguredo::mp4::endian::uint64_to_be(tc.number); 52 | BOOST_REQUIRE_EQUAL_COLLECTIONS(std::begin(tc.array), std::end(tc.array), std::begin(array), std::end(array)); 53 | const auto number = shiguredo::mp4::endian::be_to_uint64(array); 54 | BOOST_REQUIRE_EQUAL(tc.number, number); 55 | const auto number2 = shiguredo::mp4::endian::be_to_uint64(array[0], array[1], array[2], array[3], array[4], 56 | array[5], array[6], array[7]); 57 | BOOST_REQUIRE_EQUAL(tc.number, number2); 58 | } 59 | } 60 | 61 | BOOST_AUTO_TEST_SUITE_END() 62 | -------------------------------------------------------------------------------- /test/endian/main.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE "shiguredo::mp4::endian test" 2 | #include 3 | -------------------------------------------------------------------------------- /test/integration/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all get_input_files test update_input_check update_output_check 2 | 3 | all: test 4 | 5 | get_input_files: 6 | [ -f input/Big_Buck_Bunny_360_10s_1MB.mp4 ] || curl -o input/Big_Buck_Bunny_360_10s_1MB.mp4 https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/360/Big_Buck_Bunny_360_10s_1MB.mp4 # CC BY 3.0 https://creativecommons.org/licenses/by/3.0/ (c) copyright 2008, Blender Foundation / www.bigbuckbunny.org 7 | [ -f input/sample-5s.mp4 ] || curl -o input/sample-5s.mp4 https://samplelib.com/lib/download/mp4/sample-5s.mp4 # "Below are sample videos available for download with no license restrictions." -- https://samplelib.com/sample-mp4.html 8 | sha224sum -c input/check 9 | 10 | test: mux_test dump_test 11 | sha224sum -c output/check 12 | 13 | mux_test: 14 | faketime -f '2020-12-01 00:00:00' ../../release/mp4-muxer opus -f output/opus_test.mp4 --opus resources/opus.csv 15 | faketime -f '2020-12-01 00:00:00' ../../release/mp4-muxer opusvp9 -f output/opusvp9_test.mp4 --opus resources/opus.csv --vp9 resources/vp9.csv 16 | faketime -f '2020-12-01 00:00:00' ../../release/mp4-muxer opusvp9_faststart -f output/opusvp9_faststart_test.mp4 --opus resources/opus.csv --vp9 resources/vp9.csv 17 | faketime -f '2020-12-01 00:00:00' ../../release/mp4-muxer mp3vp8 -f output/mp3vp8_test.mp4 --mp3 resources/mp3.csv --vp8 resources/vp8.csv 18 | faketime -f '2020-12-01 00:00:00' ../../release/mp4-muxer aacvp9 -f output/aacvp9_test.mp4 --aac resources/aac.csv --vp9 resources/vp9.csv 19 | faketime -f '2020-12-01 00:00:00' ../../release/mp4-muxer aacvp9_faststart -f output/aacvp9_faststart_test.mp4 --aac resources/aac.csv --vp9 resources/vp9.csv 20 | faketime -f '2020-12-01 00:00:00' ../../release/mp4-muxer opusav1 -f output/opusav1_test.mp4 --opus resources/opus.csv --av1 resources/av1.csv 21 | faketime -f '2020-12-01 00:00:00' ../../release/mp4-muxer aach264 -f output/aach264_test.mp4 --aac resources/aac.csv --h264 resources/h264.csv 22 | faketime -f '2020-12-01 00:00:00' ../../release/mp4-muxer aach264_faststart -f output/aach264_faststart_test.mp4 --aac resources/aac.csv --h264 resources/h264.csv 23 | 24 | dump_test: get_input_files 25 | for f in input/*.mp4; do \ 26 | base=$$(basename $${f}); \ 27 | ../../release/mp4-tool dump -f $${f} > output/$${base}.dump; \ 28 | done 29 | 30 | 31 | update_output_check: 32 | sha224sum output/*.mp4 output/*.dump > output/check 33 | 34 | update_input_check: 35 | sha224sum input/*.mp4 > input/check 36 | -------------------------------------------------------------------------------- /test/integration/README.md: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | 3 | - curl 4 | - faketime 5 | - make 6 | - sha224sum 7 | - ../../release/mp4-tool 8 | - ../../release/mp4-muxer 9 | 10 | # Testing 11 | 12 | ``` 13 | make 14 | ``` 15 | -------------------------------------------------------------------------------- /test/integration/input/check: -------------------------------------------------------------------------------- 1 | 1c4dd31f2dd9f333405a6b7f8c2537c4c91308bab3e985d518c09cb0 input/Big_Buck_Bunny_360_10s_1MB.mp4 2 | -------------------------------------------------------------------------------- /test/integration/output/check: -------------------------------------------------------------------------------- 1 | 9833c1de3880ba1beb3ea4ad1ebf6ddfd39ae3b80b267f60ba27d61b output/aach264_faststart_test.mp4 2 | dea43f01d19b32c8a58477092fc84e40ccf63769b24d79ec2521d16d output/aach264_test.mp4 3 | 3723f9c8fbd325c694d738436f62e3e498de656c01f9049042cd6a2d output/aacvp9_faststart_test.mp4 4 | 57c737e67224eb5472ecc419443ac813f0009534212f8c227c5087cb output/aacvp9_test.mp4 5 | 2bca2680fbd1eb560cde59f959b531e42aad8d282f26fdfe11cf865c output/mp3vp8_test.mp4 6 | 41a234ed94b4403dcc328e7c48980fb8da1e6dfa2c318646c80edc3e output/opus_test.mp4 7 | ca71a3b2264a1d08fe0a2cbe0d8acb2be25e5a3908d3c05de0539d13 output/opusav1_test.mp4 8 | 1a950258de1e06b57fbd3f309b4f592db1d327e0f0c3947b4b278d69 output/opusvp9_faststart_test.mp4 9 | 233d9aede74aa7ab2a7dc1d19f13a32e48c3224a16c3ed72c4263ffe output/opusvp9_test.mp4 10 | d56c608c7dc9e34b04cdc4bdaba796d80f05b25e9856a17fa7b91b04 output/Big_Buck_Bunny_360_10s_1MB.mp4.dump 11 | 615f7fad20850cf45c0e683e2e06f9292bd59a7b342a97691787ce88 output/sample-5s.mp4.dump 12 | -------------------------------------------------------------------------------- /test/integration/resources/NOTICE: -------------------------------------------------------------------------------- 1 | aac.csv, mp3.csv, opus.csv: 2 | 3 | Converted from the .wav file at https://bigsoundbank.com/detail-0267-sea-waves-and-seagulls.html (CC0) 4 | 5 | vp8.csv, vp9.csv, av1.csv: 6 | 7 | Converted from .webm files self-made by WebRTC SFU Sora (https://sora.shiguredo.jp/) 8 | -------------------------------------------------------------------------------- /test/main.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE "shiguredo::mp4 test" 2 | #include 3 | -------------------------------------------------------------------------------- /test/time/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | add_compile_options( 4 | -Wall 5 | -Wextra 6 | -Wshadow 7 | -Wnon-virtual-dtor 8 | -Wunused 9 | -Wold-style-cast 10 | -Wcast-align 11 | -Woverloaded-virtual 12 | -Wconversion 13 | -Wsign-conversion 14 | -Wmisleading-indentation 15 | -pedantic) 16 | 17 | add_executable(time_test 18 | main.cpp 19 | time.cpp 20 | ../../src/time/time.cpp 21 | ) 22 | 23 | set_target_properties(time_test PROPERTIES CXX_STANDARD 20 C_STANDARD 11) 24 | 25 | target_include_directories(time_test PRIVATE ../../include) 26 | target_include_directories(time_test 27 | SYSTEM PRIVATE 28 | ${boost_algorithm_SOURCE_DIR}/include 29 | ${boost_assert_SOURCE_DIR}/include 30 | ${boost_bind_SOURCE_DIR}/include 31 | ${boost_config_SOURCE_DIR}/include 32 | ${boost_container_hash_SOURCE_DIR}/include 33 | ${boost_core_SOURCE_DIR}/include 34 | ${boost_describe_SOURCE_DIR}/include 35 | ${boost_detail_SOURCE_DIR}/include 36 | ${boost_exception_SOURCE_DIR}/include 37 | ${boost_function_SOURCE_DIR}/include 38 | ${boost_integer_SOURCE_DIR}/include 39 | ${boost_io_SOURCE_DIR}/include 40 | ${boost_iterator_SOURCE_DIR}/include 41 | ${boost_move_SOURCE_DIR}/include 42 | ${boost_mp11_SOURCE_DIR}/include 43 | ${boost_mpl_SOURCE_DIR}/include 44 | ${boost_numeric_conversion_SOURCE_DIR}/include 45 | ${boost_preprocessor_SOURCE_DIR}/include 46 | ${boost_range_SOURCE_DIR}/include 47 | ${boost_smart_ptr_SOURCE_DIR}/include 48 | ${boost_static_assert_SOURCE_DIR}/include 49 | ${boost_test_SOURCE_DIR}/include 50 | ${boost_throw_exception_SOURCE_DIR}/include 51 | ${boost_type_index_SOURCE_DIR}/include 52 | ${boost_type_traits_SOURCE_DIR}/include 53 | ${boost_utility_SOURCE_DIR}/include 54 | ${fmt_SOURCE_DIR}/include 55 | ) 56 | 57 | target_link_libraries(time_test 58 | PRIVATE 59 | fmt 60 | ) 61 | 62 | add_test(NAME time COMMAND time_test) 63 | -------------------------------------------------------------------------------- /test/time/main.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE "shiguredo::mp4::time test" 2 | #include 3 | -------------------------------------------------------------------------------- /test/time/time.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "shiguredo/mp4/time/time.hpp" 7 | 8 | BOOST_AUTO_TEST_SUITE(mp4_time) 9 | 10 | struct TimeTestCase { 11 | const std::uint64_t from_epoch_19700101; 12 | const std::uint64_t from_epoch_19040101; 13 | const std::string formated; 14 | }; 15 | 16 | TimeTestCase time_test_cases[] = { 17 | { 18 | 0, 19 | 2082844800, 20 | "1970-01-01T00:00:00Z", 21 | }, 22 | { 23 | 0x7fffffff, 24 | 4230328447, 25 | "2038-01-19T03:14:07Z", 26 | }, 27 | { 28 | 0xffffffff, 29 | 6377812095, 30 | "2106-02-07T06:28:15Z", 31 | }, 32 | { 33 | 0x100000000, 34 | 6377812096, 35 | "0000-00-00T00:00:00Z", 36 | }, 37 | }; 38 | 39 | BOOST_AUTO_TEST_CASE(epoch) { 40 | BOOST_TEST_MESSAGE("epoch"); 41 | for (const auto& tc : time_test_cases) { 42 | const auto from_epoch_19040101 = shiguredo::mp4::time::convert_to_epoch_19040101(tc.from_epoch_19700101); 43 | BOOST_REQUIRE_EQUAL(tc.from_epoch_19040101, from_epoch_19040101); 44 | BOOST_REQUIRE_EQUAL(tc.formated, shiguredo::mp4::time::format_epoch_19040101(from_epoch_19040101)); 45 | } 46 | } 47 | 48 | BOOST_AUTO_TEST_SUITE_END() 49 | -------------------------------------------------------------------------------- /test/track/h264.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include "shiguredo/mp4/track/h264.hpp" 8 | 9 | BOOST_AUTO_TEST_SUITE(h264) 10 | 11 | struct FindNextNalUnitNormalTestCase { 12 | const std::vector data; 13 | const std::size_t start; 14 | const shiguredo::mp4::track::NalUnit nal_unit; 15 | }; 16 | 17 | FindNextNalUnitNormalTestCase find_next_nal_unit_normal_test_case[] = { 18 | { 19 | {0, 0, 0, 1, 67, 1, 2}, 20 | 0, 21 | shiguredo::mp4::track::NalUnit{4, 0, 7, 67}, 22 | }, 23 | { 24 | {0, 0, 0, 1, 68, 1, 2, 3}, 25 | 0, 26 | shiguredo::mp4::track::NalUnit{4, 0, 8, 68}, 27 | }, 28 | { 29 | {0, 0, 0, 1, 68, 1, 2, 3, 4, 0, 0, 1, 65, 1, 2, 3}, 30 | 0, 31 | shiguredo::mp4::track::NalUnit{4, 0, 9, 68}, 32 | }, 33 | { 34 | {0, 0, 0, 1, 68, 1, 2, 3, 4, 0, 0, 1, 65, 1, 2, 3}, 35 | 9, 36 | shiguredo::mp4::track::NalUnit{3, 9, 16, 65}, 37 | }, 38 | { 39 | {0, 0, 1, 61, 1, 2, 3}, 40 | 0, 41 | shiguredo::mp4::track::NalUnit{3, 0, 7, 61}, 42 | }, 43 | }; 44 | 45 | BOOST_AUTO_TEST_CASE(find_next_nal_unit_normal) { 46 | BOOST_TEST_MESSAGE("find_next_nal_unit_normal"); 47 | for (const auto& tc : find_next_nal_unit_normal_test_case) { 48 | auto nal_unit = shiguredo::mp4::track::find_next_nal_unit(tc.data.data(), tc.data.size(), tc.start); 49 | BOOST_REQUIRE_EQUAL(tc.nal_unit, nal_unit); 50 | } 51 | } 52 | 53 | struct FindNextNalUnitRuntimeErrorTestCase { 54 | const std::vector data; 55 | const std::size_t start; 56 | }; 57 | 58 | FindNextNalUnitRuntimeErrorTestCase find_next_nal_unit_runtime_error_test_case[] = { 59 | { 60 | {0, 0, 0, 1, 68, 1, 2, 3}, 61 | 2, 62 | }, 63 | { 64 | {0, 0, 0, 1, 68, 1, 2, 3}, 65 | 3, 66 | }, 67 | { 68 | {0, 0, 0, 1, 68, 1, 2, 3}, 69 | 4, 70 | }, 71 | { 72 | {0, 0, 0, 1, 68, 1, 2, 3}, 73 | 10, 74 | }, 75 | { 76 | {0, 0, 0, 1, 68, 1, 2, 3, 4, 0, 0, 1, 65, 1, 2, 3}, 77 | 8, 78 | }, 79 | { 80 | {0, 0, 0, 1, 68, 1, 2, 3, 4, 0, 0, 1, 65, 1, 2, 3}, 81 | 10, 82 | }, 83 | { 84 | {0, 0, 1, 61, 1, 2, 3}, 85 | 1, 86 | }, 87 | }; 88 | 89 | BOOST_AUTO_TEST_CASE(find_next_nal_unit_runtime_error) { 90 | BOOST_TEST_MESSAGE("find_next_nal_unit_runtime_error"); 91 | for (const auto& tc : find_next_nal_unit_runtime_error_test_case) { 92 | BOOST_REQUIRE_THROW(shiguredo::mp4::track::find_next_nal_unit(tc.data.data(), tc.data.size(), tc.start), 93 | std::runtime_error); 94 | } 95 | } 96 | 97 | BOOST_AUTO_TEST_SUITE_END() 98 | -------------------------------------------------------------------------------- /test/track/main.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE "shiguredo::mp4::track test" 2 | #include 3 | -------------------------------------------------------------------------------- /test/version.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "shiguredo/mp4/version.hpp" 6 | 7 | BOOST_AUTO_TEST_SUITE(version) 8 | 9 | BOOST_AUTO_TEST_CASE(version_string) { 10 | BOOST_REQUIRE_EQUAL("2023.2.1", shiguredo::mp4::get_version_string()); 11 | } 12 | 13 | BOOST_AUTO_TEST_SUITE_END() 14 | --------------------------------------------------------------------------------