diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..cb200fe --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,260 @@ +cmake_minimum_required(VERSION 3.6) +#project(mp4v2_2_0_0) +project(mp4v2_1_0_0 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 11) +#set(CMAKE_CXX_STANDARD 17) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Do not allow in-source build. +if( ${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR} ) + message( FATAL_ERROR "In-source build is not allowed. Please build in a separate directory, such as ${PROJECT_SOURCE_DIR}/build." ) +endif() + +include_directories("${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/include") + +set(PROJECT_repo_rev 0) + +configure_file(${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/project.h.in ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/project.h) +configure_file(${CMAKE_CURRENT_LIST_DIR}/libplatform/config.h.in ${CMAKE_CURRENT_LIST_DIR}/libplatform/config.h) + +set(HEADER_FILES + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/chapter.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/file.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/file_prop.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/general.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/isma.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/itmf_generic.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/itmf_tags.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/mp4v2.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/platform.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/project.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/sample.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/streaming.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/track.h + ${CMAKE_CURRENT_LIST_DIR}/include/mp4v2/track_prop.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/io/File.cpp + ${CMAKE_CURRENT_LIST_DIR}/libplatform/io/File.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/io/FileSystem.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/number/random.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/process/process.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/prog/option.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/sys/error.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/time/time.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/config.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/endian.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/impl.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/platform.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/platform_base.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/platform_posix.h + ${CMAKE_CURRENT_LIST_DIR}/libplatform/warning.h + ${CMAKE_CURRENT_LIST_DIR}/libutil/crc.h + ${CMAKE_CURRENT_LIST_DIR}/libutil/Database.h + ${CMAKE_CURRENT_LIST_DIR}/libutil/impl.h + ${CMAKE_CURRENT_LIST_DIR}/libutil/other.h + ${CMAKE_CURRENT_LIST_DIR}/libutil/Timecode.h + ${CMAKE_CURRENT_LIST_DIR}/libutil/TrackModifier.h + ${CMAKE_CURRENT_LIST_DIR}/libutil/util.h + ${CMAKE_CURRENT_LIST_DIR}/libutil/Utility.h + ${CMAKE_CURRENT_LIST_DIR}/src/bmff/bmff.h + ${CMAKE_CURRENT_LIST_DIR}/src/bmff/impl.h + ${CMAKE_CURRENT_LIST_DIR}/src/bmff/typebmff.h + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/CoverArtBox.h + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/generic.h + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/impl.h + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/itmf.h + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/Tags.h + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/type.h + ${CMAKE_CURRENT_LIST_DIR}/src/qtff/coding.h + ${CMAKE_CURRENT_LIST_DIR}/src/qtff/ColorParameterBox.h + ${CMAKE_CURRENT_LIST_DIR}/src/qtff/impl.h + ${CMAKE_CURRENT_LIST_DIR}/src/qtff/PictureAspectRatioBox.h + ${CMAKE_CURRENT_LIST_DIR}/src/qtff/qtff.h + ${CMAKE_CURRENT_LIST_DIR}/src/atoms.h + ${CMAKE_CURRENT_LIST_DIR}/src/descriptors.h + ${CMAKE_CURRENT_LIST_DIR}/src/enum.h + ${CMAKE_CURRENT_LIST_DIR}/src/exception.h + ${CMAKE_CURRENT_LIST_DIR}/src/impl.h + ${CMAKE_CURRENT_LIST_DIR}/src/log.h + ${CMAKE_CURRENT_LIST_DIR}/src/mp4array.h + ${CMAKE_CURRENT_LIST_DIR}/src/mp4atom.h + ${CMAKE_CURRENT_LIST_DIR}/src/mp4container.h + ${CMAKE_CURRENT_LIST_DIR}/src/mp4descriptor.h + ${CMAKE_CURRENT_LIST_DIR}/src/mp4file.h + ${CMAKE_CURRENT_LIST_DIR}/src/mp4property.h + ${CMAKE_CURRENT_LIST_DIR}/src/mp4track.h + ${CMAKE_CURRENT_LIST_DIR}/src/mp4util.h + ${CMAKE_CURRENT_LIST_DIR}/src/ocidescriptors.h + ${CMAKE_CURRENT_LIST_DIR}/src/odcommands.h + ${CMAKE_CURRENT_LIST_DIR}/src/qosqualifiers.h + ${CMAKE_CURRENT_LIST_DIR}/src/rtphint.h + ${CMAKE_CURRENT_LIST_DIR}/src/src.h + ${CMAKE_CURRENT_LIST_DIR}/src/text.h + ${CMAKE_CURRENT_LIST_DIR}/src/util.h) + +set(SOURCE_FILES + ${CMAKE_CURRENT_LIST_DIR}/libplatform/io/File_posix.cpp + ${CMAKE_CURRENT_LIST_DIR}/libplatform/io/FileSystem.cpp + ${CMAKE_CURRENT_LIST_DIR}/libplatform/io/FileSystem_posix.cpp + ${CMAKE_CURRENT_LIST_DIR}/libplatform/number/random_posix.cpp + ${CMAKE_CURRENT_LIST_DIR}/libplatform/process/process_posix.cpp + ${CMAKE_CURRENT_LIST_DIR}/libplatform/prog/option.cpp + ${CMAKE_CURRENT_LIST_DIR}/libplatform/sys/error.cpp + ${CMAKE_CURRENT_LIST_DIR}/libplatform/time/time.cpp + ${CMAKE_CURRENT_LIST_DIR}/libplatform/time/time_posix.cpp + ${CMAKE_CURRENT_LIST_DIR}/libutil/crc.cpp + ${CMAKE_CURRENT_LIST_DIR}/libutil/Database.cpp + ${CMAKE_CURRENT_LIST_DIR}/libutil/other.cpp + ${CMAKE_CURRENT_LIST_DIR}/libutil/Timecode.cpp + ${CMAKE_CURRENT_LIST_DIR}/libutil/TrackModifier.cpp + ${CMAKE_CURRENT_LIST_DIR}/libutil/Utility.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/bmff/typebmff.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/CoverArtBox.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/generic.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/Tags.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/itmf/type.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/qtff/coding.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/qtff/ColorParameterBox.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/qtff/PictureAspectRatioBox.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/3gp.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_ac3.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_amr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_av1C.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_avc1.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_avcC.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_avxx.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_chpl.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_colr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_d263.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_dac3.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_damr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_dref.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_dops.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_elst.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_enca.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_encv.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_free.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_ftab.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_ftyp.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_gmin.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_hdlr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_hinf.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_hnti.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_href.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_mdat.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_mdhd.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_meta.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_mp4s.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_mp4v.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_mvhd.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_nmhd.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_ohdr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_opus.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_pasp.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_root.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_rtp.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_s263.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_sdp.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_sdtp.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_smi.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_sound.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_standard.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_stbl.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_stdp.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_stsc.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_stsd.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_stsz.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_stz2.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_text.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_tfhd.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_tkhd.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_treftype.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_trun.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_tx3g.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_udta.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_url.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_urn.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_uuid.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_video.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_vpcC.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_vpxx.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_vmhd.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cmeta.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/descriptors.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/enum.tcc + ${CMAKE_CURRENT_LIST_DIR}/src/exception.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/isma.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/log.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4atom.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4container.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4descriptor.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4file.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4file_io.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4info.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4property.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4track.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mp4util.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ocidescriptors.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/odcommands.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/qosqualifiers.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/rtphint.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/text.cpp +) + +add_library(mp4v2-shared SHARED ${HEADER_FILES} ${SOURCE_FILES}) +target_include_directories(mp4v2-shared PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/include +) +target_compile_options(mp4v2-shared PUBLIC -Wno-narrowing) + +add_library(mp4v2-static STATIC ${HEADER_FILES} ${SOURCE_FILES}) +target_include_directories(mp4v2-static PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/include +) + +target_compile_options(mp4v2-static PUBLIC -Wno-narrowing) + +#for debugging +#target_compile_options(mp4v2-static PUBLIC +# -Wliteral-suffix +# -ggdb +# -O0 +#) + + +set(UTILITY_HEADERS + ${CMAKE_CURRENT_LIST_DIR}/util/impl.h) + +add_executable(mp4art ${UTILITY_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/util/mp4art.cpp) +target_link_libraries(mp4art mp4v2-static) + +add_executable(mp4chaps ${UTILITY_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/util/mp4chaps.cpp) +target_link_libraries(mp4chaps mp4v2-static) + +add_executable(mp4extract ${UTILITY_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/util/mp4extract.cpp) +target_link_libraries(mp4extract mp4v2-static) + +add_executable(mp4file ${UTILITY_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/util/mp4file.cpp) +target_link_libraries(mp4file mp4v2-static) + +add_executable(mp4info ${UTILITY_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/util/mp4info.cpp) +target_link_libraries(mp4info mp4v2-static) + +add_executable(mp4subtitle ${UTILITY_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/util/mp4subtitle.cpp) +target_link_libraries(mp4subtitle mp4v2-static) + +add_executable(mp4tags ${UTILITY_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/util/mp4tags.cpp) +target_link_libraries(mp4tags mp4v2-static) + +add_executable(mp4track ${UTILITY_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/util/mp4track.cpp) +target_link_libraries(mp4track mp4v2-static) + +add_executable(mp4trackdump ${UTILITY_HEADERS} ${CMAKE_CURRENT_LIST_DIR}/util/mp4trackdump.cpp) +target_link_libraries(mp4trackdump mp4v2-static) + diff --git a/GNUmakefile.am b/GNUmakefile.am index 947e6e3..4bf55a6 100644 --- a/GNUmakefile.am +++ b/GNUmakefile.am @@ -14,8 +14,14 @@ libmp4v2_la_SOURCES = \ src/3gp.cpp \ src/atom_ac3.cpp \ src/atom_amr.cpp \ + src/atom_av1C.cpp \ src/atom_avc1.cpp \ src/atom_avcC.cpp \ + src/atom_avxx.cpp \ + src/atom_vpxx.cpp \ + src/atom_vpcC.cpp \ + src/atom_opus.cpp \ + src/atom_dops.cpp \ src/atom_chpl.cpp \ src/atom_colr.cpp \ src/atom_d263.cpp \ diff --git a/include/mp4v2/general.h b/include/mp4v2/general.h index f9713bf..9d0caa2 100644 --- a/include/mp4v2/general.h +++ b/include/mp4v2/general.h @@ -128,6 +128,7 @@ typedef uint32_t (*encryptFunc_t)( uint32_t, uint32_t, uint8_t*, uint32_t*, uint #define MP4_ULAW_AUDIO_TYPE 0xE4 /* a private definition */ #define MP4_G723_AUDIO_TYPE 0xE5 /* a private definition */ #define MP4_PCM16_BIG_ENDIAN_AUDIO_TYPE 0xE6 /* a private definition */ +#define MP4_OPUS_AUDIO_TYPE 0xE7 /* a private definition */ /* MP4 MPEG-4 Audio types from 14496-3 Table 1.5.1 */ #define MP4_MPEG4_INVALID_AUDIO_TYPE 0 @@ -184,6 +185,9 @@ typedef uint32_t (*encryptFunc_t)( uint32_t, uint32_t, uint8_t*, uint32_t*, uint #define MP4_YUV12_VIDEO_TYPE 0xF0 /* a private definition */ #define MP4_H263_VIDEO_TYPE 0xF2 /* a private definition */ #define MP4_H261_VIDEO_TYPE 0xF3 /* a private definition */ +#define MP4_VP8_VIDEO_TYPE 0xF4 /* a private definition */ +#define MP4_VP9_VIDEO_TYPE 0xF5 /* a private definition */ +#define MP4_AV1_VIDEO_TYPE 0xF6 /* a private definition */ /* MP4 Video type utilities */ #define MP4_IS_MPEG1_VIDEO_TYPE(type) \ diff --git a/include/mp4v2/track.h b/include/mp4v2/track.h index 90eb7bc..80b0bd3 100644 --- a/include/mp4v2/track.h +++ b/include/mp4v2/track.h @@ -124,6 +124,13 @@ MP4TrackId MP4AddAudioTrack( MP4Duration sampleDuration, uint8_t audioType DEFAULT(MP4_MPEG4_AUDIO_TYPE) ); +MP4V2_EXPORT +MP4TrackId MP4AddOpusAudioTrack( + MP4FileHandle hFile, + uint32_t timeScale, + uint16_t channelCount, + uint32_t samplingRate); + /** Add ulaw track to mp4 file. * * MP4AddULawAudioTrack adds a ulaw track to the mp4 file. MP4WriteSample() @@ -246,6 +253,30 @@ MP4TrackId MP4AddVideoTrack( uint16_t height, uint8_t videoType DEFAULT(MP4_MPEG4_VIDEO_TYPE) ); +MP4V2_EXPORT +MP4TrackId MP4AddAV1VideoTrack( + MP4FileHandle hFile, + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height); + +MP4V2_EXPORT +MP4TrackId MP4AddVP8VideoTrack( + MP4FileHandle hFile, + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height ); + +MP4V2_EXPORT +MP4TrackId MP4AddVP9VideoTrack( + MP4FileHandle hFile, + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height ); + MP4V2_EXPORT MP4TrackId MP4AddH264VideoTrack( MP4FileHandle hFile, @@ -272,6 +303,14 @@ void MP4AddH264PictureParameterSet( const uint8_t* pPict, uint16_t pictLen ); +MP4V2_EXPORT +void MP4SetAv1SequenceObu( + MP4FileHandle hFile, + MP4TrackId trackId, + const uint8_t* pSequence, + uint16_t sequenceLen); + + MP4V2_EXPORT void MP4SetH263Vendor( MP4FileHandle hFile, diff --git a/libplatform/config.h.in b/libplatform/config.h.in index 47a5a04..f501a09 100644 --- a/libplatform/config.h.in +++ b/libplatform/config.h.in @@ -30,8 +30,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ +/* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if LFS should be activated */ diff --git a/libutil/Utility.cpp b/libutil/Utility.cpp index 76cdd12..2c7cda4 100644 --- a/libutil/Utility.cpp +++ b/libutil/Utility.cpp @@ -531,26 +531,26 @@ Utility::process_impl() printHelp( false, false ); return SUCCESS; - case LC_DEBUG: + case static_cast(LC_DEBUG): debugUpdate( std::strtoul( prog::optarg, NULL, 0 ) ); break; - case LC_VERBOSE: + case static_cast(LC_VERBOSE): { const uint32_t level = std::strtoul( prog::optarg, NULL, 0 ); _verbosity = ( level < 4 ) ? level : 3; break; } - case LC_HELP: + case static_cast(LC_HELP): printHelp( true, false ); return SUCCESS; - case LC_VERSION: + case static_cast(LC_VERSION): printVersion( false ); return SUCCESS; - case LC_VERSIONX: + case static_cast(LC_VERSIONX): printVersion( true ); return SUCCESS; diff --git a/src/atom_av1C.cpp b/src/atom_av1C.cpp new file mode 100644 index 0000000..1050750 --- /dev/null +++ b/src/atom_av1C.cpp @@ -0,0 +1,71 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is MPEG4IP. + * + * The Initial Developer of the Original Code is Cisco Systems Inc. + * Portions created by Cisco Systems Inc. are + * Copyright (C) Cisco Systems Inc. 2004. All Rights Reserved. + * + * Contributor(s): + * Bill May wmay@cisco.com + */ + +#include "src/impl.h" + +namespace mp4v2 { +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// + +MP4Av1CAtom::MP4Av1CAtom(MP4File &file) + : MP4Atom(file, "av1C") +{ + AddProperty( new MP4BitfieldProperty(*this, "marker", 1)); /* 0 */ + AddProperty( new MP4BitfieldProperty(*this, "version", 7)); /* 1 */ + AddProperty( new MP4BitfieldProperty(*this, "seq_profile", 3)); /* 2 */ + AddProperty( new MP4BitfieldProperty(*this, "seq_level_idx_0", 5)); /* 3 */ + AddProperty( new MP4BitfieldProperty(*this, "seq_tier_0", 1)); /* 4 */ + AddProperty( new MP4BitfieldProperty(*this, "high_bitdepth", 1)); /* 5 */ + AddProperty( new MP4BitfieldProperty(*this, "twelve_bit", 1)); /* 6 */ + AddProperty( new MP4BitfieldProperty(*this, "monochrome", 1)); /* 7 */ + AddProperty( new MP4BitfieldProperty(*this, "chroma_subsampling_x", 1)); /* 8 */ + AddProperty( new MP4BitfieldProperty(*this, "chroma_subsampling_y", 1)); /* 9 */ + AddProperty( new MP4BitfieldProperty(*this, "chroma_sample_position", 2)); /* 10 */ + AddProperty( new MP4BitfieldProperty(*this, "reserved ", 3)); /* 11 */ + AddProperty( new MP4BitfieldProperty(*this, "initial_presentation_delay_present", 1)); /* 12 */ + AddProperty( new MP4BitfieldProperty(*this, "initial_presentation_delay_minus_one_or_reserved", 4)); /* 13 */ + AddProperty( new MP4BytesProperty(*this, "configOBUs", 0)); /* 14 */ +} + + +void MP4Av1CAtom::Generate() +{ + MP4Atom::Generate(); + ((MP4BitfieldProperty*)m_pProperties[0])->SetValue(1); + ((MP4BitfieldProperty*)m_pProperties[1])->SetValue(1); + ((MP4BitfieldProperty*)m_pProperties[2])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[3])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[4])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[5])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[6])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[7])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[8])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[9])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[10])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[11])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[12])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[13])->SetValue(0); +} +/////////////////////////////////////////////////////////////////////////////// + +} +} // namespace mp4v2::impl diff --git a/src/atom_avxx.cpp b/src/atom_avxx.cpp new file mode 100644 index 0000000..77936b3 --- /dev/null +++ b/src/atom_avxx.cpp @@ -0,0 +1,89 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is MPEG4IP. + * + * The Initial Developer of the Original Code is Cisco Systems Inc. + * Portions created by Cisco Systems Inc. are + * Copyright (C) Cisco Systems Inc. 2004. All Rights Reserved. + * + * Contributor(s): + * Bill May wmay@cisco.com + */ + +#include "src/impl.h" + +namespace mp4v2 { +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// + +MP4Av01Atom::MP4Av01Atom(MP4File& file) + : MP4Atom(file, "av01") +{ + AddReserved(*this, "reserved1", 6); /* 0 */ + + AddProperty( /* 1 */ + new MP4Integer16Property(*this, "dataReferenceIndex")); + + AddReserved(*this, "reserved2", 16); /* 2 */ + + AddProperty( /* 3 */ + new MP4Integer16Property(*this, "width")); + AddProperty( /* 4 */ + new MP4Integer16Property(*this, "height")); + + AddReserved(*this, "reserved3", 14); /* 5 */ + + MP4StringProperty* pProp = + new MP4StringProperty(*this, "compressorName"); + pProp->SetFixedLength(32); + pProp->SetCountedFormat(true); + pProp->SetValue("AV1 Coding"); + AddProperty(pProp); /* 6 */ + + AddReserved(*this, "reserved4", 4); /* 7 */ + + ExpectChildAtom("av1C", Required, OnlyOne); +} + +void MP4Av01Atom::Generate() +{ + MP4Atom::Generate(); + + ((MP4Integer16Property*)m_pProperties[1])->SetValue(1); + + // property reserved3 has non-zero fixed values + static uint8_t reserved3[14] = { + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, + }; + m_pProperties[5]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[5])-> + SetValue(reserved3, sizeof(reserved3)); + m_pProperties[5]->SetReadOnly(true); + + // property reserved4 has non-zero fixed values + static uint8_t reserved4[4] = { + 0x00, 0x18, 0xFF, 0xFF, + }; + m_pProperties[7]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[7])-> + SetValue(reserved4, sizeof(reserved4)); + m_pProperties[7]->SetReadOnly(true); +} + +/////////////////////////////////////////////////////////////////////////////// + +} +} // namespace mp4v2::impl diff --git a/src/atom_dops.cpp b/src/atom_dops.cpp new file mode 100644 index 0000000..d28b960 --- /dev/null +++ b/src/atom_dops.cpp @@ -0,0 +1,54 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is MPEG4IP. + * + * The Initial Developer of the Original Code is Cisco Systems Inc. + * Portions created by Cisco Systems Inc. are + * Copyright (C) Cisco Systems Inc. 2004. All Rights Reserved. + * + * Contributor(s): + * Bill May wmay@cisco.com + */ + +#include "src/impl.h" + +namespace mp4v2 { +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// + +MP4DOpsAtom::MP4DOpsAtom(MP4File &file) + : MP4Atom(file, "dOps") +{ + + AddProperty( new MP4Integer8Property(*this,"version")); /* 0 */ + AddProperty( new MP4Integer8Property(*this,"outputChannelCount")); /* 1 */ + AddProperty( new MP4Integer16Property(*this,"preSkip")); /* 2 */ + AddProperty( new MP4Integer32Property(*this,"inputSampleRate")); /* 3 */ + AddProperty( new MP4Integer16Property(*this,"outputGain")); /* 4 */ + AddProperty( new MP4Integer8Property(*this,"channelMappingFamily")); /* 5 */ +} + +void MP4DOpsAtom::Generate() +{ + MP4Atom::Generate(); + ((MP4Integer8Property*)m_pProperties[0])->SetValue(0); + ((MP4Integer8Property*)m_pProperties[1])->SetValue(2); + ((MP4Integer16Property*)m_pProperties[2])->SetValue(0); + ((MP4Integer32Property*)m_pProperties[3])->SetValue(48000); + ((MP4Integer32Property*)m_pProperties[4])->SetValue(0); + ((MP4Integer32Property*)m_pProperties[5])->SetValue(0); +} +/////////////////////////////////////////////////////////////////////////////// + +} +} // namespace mp4v2::impl diff --git a/src/atom_opus.cpp b/src/atom_opus.cpp new file mode 100644 index 0000000..5fda5cb --- /dev/null +++ b/src/atom_opus.cpp @@ -0,0 +1,70 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is MPEG4IP. + * + * The Initial Developer of the Original Code is Cisco Systems Inc. + * Portions created by Cisco Systems Inc. are + * Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved. + * + * See ETSI TS 102 366 V1.2.1 Annex F for how to put Ac3 in MP4. + * + * Contributor(s): + * Edward Groenendaal egroenen@cisco.com + */ + +#include "src/impl.h" + +namespace mp4v2 { +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// + +MP4OpusAtom::MP4OpusAtom(MP4File &file) + : MP4Atom(file, "Opus") +{ + AddReserved(*this, "reserved1", 6); /* 0 */ + + AddProperty( /* 1 */ + new MP4Integer16Property(*this,"dataReferenceIndex")); + + AddReserved(*this,"reserved2", 8); /* 2 */ + + AddProperty( /* 3 */ + new MP4Integer16Property(*this,"channelCount")); + + AddProperty( /* 4 */ + new MP4Integer16Property(*this,"sampleSize")); + + AddReserved(*this,"reserved3", 4); /* 5 */ + + AddProperty( /* 6 */ + new MP4Integer16Property(*this,"samplingRate")); + + AddReserved(*this,"reserved4", 2); /* 7 */ + + ExpectChildAtom("dOps", Required, OnlyOne); +} + +void MP4OpusAtom::Generate() +{ + MP4Atom::Generate(); + + ((MP4Integer16Property*)m_pProperties[1])->SetValue(1); // data-reference-index + ((MP4Integer16Property*)m_pProperties[3])->SetValue(2); // channelCount - should be overriden + ((MP4Integer16Property*)m_pProperties[4])->SetValue(16); // The samplesize field shall be set to 16 + ((MP4Integer16Property*)m_pProperties[6])->SetValue(48000<<16); //The samplerate field shall be set to 48000<<16. + } + +/////////////////////////////////////////////////////////////////////////////// + +} +} // namespace mp4v2::impl diff --git a/src/atom_vpcC.cpp b/src/atom_vpcC.cpp new file mode 100644 index 0000000..b8f51f8 --- /dev/null +++ b/src/atom_vpcC.cpp @@ -0,0 +1,60 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is MPEG4IP. + * + * The Initial Developer of the Original Code is Cisco Systems Inc. + * Portions created by Cisco Systems Inc. are + * Copyright (C) Cisco Systems Inc. 2004. All Rights Reserved. + * + * Contributor(s): + * Bill May wmay@cisco.com + */ + +#include "src/impl.h" + +namespace mp4v2 { +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// + +MP4VpcCAtom::MP4VpcCAtom(MP4File &file) + : MP4FullAtom(file, "vpcC") +{ + + AddProperty( new MP4Integer8Property(*this,"profile")); /* 0 */ + AddProperty( new MP4Integer8Property(*this,"level")); /* 1 */ + AddProperty( new MP4BitfieldProperty(*this,"bitDepth" ,4)); /* 2 */ + AddProperty( new MP4BitfieldProperty(*this,"colorSpace", 4)); /* 3 */ + AddProperty( new MP4BitfieldProperty(*this,"chromaSubsampling", 4)); /* 4 */ + AddProperty( new MP4BitfieldProperty(*this,"transferFunction", 3)); /* 5 */ + AddProperty( new MP4BitfieldProperty(*this,"videoFullRangeFlag", 1)); /* 6 */ + AddProperty( new MP4Integer16Property(*this,"codecIntializationDataSize")); /* 7 */ + AddProperty( new MP4BytesProperty(*this,"codecIntializationData",0)); /* 8 */ +} + +void MP4VpcCAtom::Generate() +{ + MP4FullAtom::Generate(); + ((MP4Integer8Property*)m_pProperties[0])->SetValue(0); + ((MP4Integer8Property*)m_pProperties[1])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[2])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[3])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[4])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[5])->SetValue(0); + ((MP4BitfieldProperty*)m_pProperties[6])->SetValue(0); + ((MP4Integer16Property*)m_pProperties[7])->SetValue(0); + //((MP4BytesProperty*)m_pProperties[8])->SetValueSize(0,0); +} +/////////////////////////////////////////////////////////////////////////////// + +} +} // namespace mp4v2::impl diff --git a/src/atom_vpxx.cpp b/src/atom_vpxx.cpp new file mode 100644 index 0000000..20db568 --- /dev/null +++ b/src/atom_vpxx.cpp @@ -0,0 +1,211 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is MPEG4IP. + * + * The Initial Developer of the Original Code is Cisco Systems Inc. + * Portions created by Cisco Systems Inc. are + * Copyright (C) Cisco Systems Inc. 2004. All Rights Reserved. + * + * Contributor(s): + * Bill May wmay@cisco.com + */ + +#include "src/impl.h" + +namespace mp4v2 { +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// + +MP4Vp08Atom::MP4Vp08Atom(MP4File &file) + : MP4Atom(file, "vp08") +{ + AddReserved(*this, "reserved1", 6); /* 0 */ + + AddProperty( /* 1 */ + new MP4Integer16Property(*this, "dataReferenceIndex")); + + AddReserved(*this, "reserved2", 16); /* 2 */ + + AddProperty( /* 3 */ + new MP4Integer16Property(*this, "width")); + AddProperty( /* 4 */ + new MP4Integer16Property(*this, "height")); + + AddReserved(*this, "reserved3", 14); /* 5 */ + + MP4StringProperty* pProp = + new MP4StringProperty(*this, "compressorName"); + pProp->SetFixedLength(32); + pProp->SetCountedFormat(true); + pProp->SetValue("VPC Coding"); + AddProperty(pProp); /* 6 */ + + AddReserved(*this, "reserved4", 4); /* 7 */ + + ExpectChildAtom("vpcC", Required, OnlyOne); +} + +void MP4Vp08Atom::Generate() +{ + MP4Atom::Generate(); + + ((MP4Integer16Property*)m_pProperties[1])->SetValue(1); + + // property reserved3 has non-zero fixed values + static uint8_t reserved3[14] = { + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, + }; + m_pProperties[5]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[5])-> + SetValue(reserved3, sizeof(reserved3)); + m_pProperties[5]->SetReadOnly(true); + + // property reserved4 has non-zero fixed values + static uint8_t reserved4[4] = { + 0x00, 0x18, 0xFF, 0xFF, + }; + m_pProperties[7]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[7])-> + SetValue(reserved4, sizeof(reserved4)); + m_pProperties[7]->SetReadOnly(true); +} + +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// + +MP4Vp09Atom::MP4Vp09Atom(MP4File &file) + : MP4Atom(file, "vp09") +{ + AddReserved(*this, "reserved1", 6); /* 0 */ + + AddProperty( /* 1 */ + new MP4Integer16Property(*this, "dataReferenceIndex")); + + AddReserved(*this, "reserved2", 16); /* 2 */ + + AddProperty( /* 3 */ + new MP4Integer16Property(*this, "width")); + AddProperty( /* 4 */ + new MP4Integer16Property(*this, "height")); + + AddReserved(*this, "reserved3", 14); /* 5 */ + + MP4StringProperty* pProp = + new MP4StringProperty(*this, "compressorName"); + pProp->SetFixedLength(32); + pProp->SetCountedFormat(true); + pProp->SetValue("VPC Coding"); + AddProperty(pProp); /* 6 */ + + AddReserved(*this, "reserved4", 4); /* 7 */ + + ExpectChildAtom("vpcC", Required, OnlyOne); +} + +void MP4Vp09Atom::Generate() +{ + MP4Atom::Generate(); + + ((MP4Integer16Property*)m_pProperties[1])->SetValue(1); + + // property reserved3 has non-zero fixed values + static uint8_t reserved3[14] = { + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, + }; + m_pProperties[5]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[5])-> + SetValue(reserved3, sizeof(reserved3)); + m_pProperties[5]->SetReadOnly(true); + + // property reserved4 has non-zero fixed values + static uint8_t reserved4[4] = { + 0x00, 0x18, 0xFF, 0xFF, + }; + m_pProperties[7]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[7])-> + SetValue(reserved4, sizeof(reserved4)); + m_pProperties[7]->SetReadOnly(true); +} + +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// + +MP4Vp10Atom::MP4Vp10Atom(MP4File &file) + : MP4Atom(file, "vp10") +{ + AddReserved(*this, "reserved1", 6); /* 0 */ + + AddProperty( /* 1 */ + new MP4Integer16Property(*this, "dataReferenceIndex")); + + AddReserved(*this, "reserved2", 16); /* 2 */ + + AddProperty( /* 3 */ + new MP4Integer16Property(*this, "width")); + AddProperty( /* 4 */ + new MP4Integer16Property(*this, "height")); + + AddReserved(*this, "reserved3", 14); /* 5 */ + + MP4StringProperty* pProp = + new MP4StringProperty(*this, "compressorName"); + pProp->SetFixedLength(32); + pProp->SetCountedFormat(true); + pProp->SetValue("VPC Coding"); + AddProperty(pProp); /* 6 */ + + AddReserved(*this, "reserved4", 4); /* 7 */ + + ExpectChildAtom("vpcC", Required, OnlyOne); +} + +void MP4Vp10Atom::Generate() +{ + MP4Atom::Generate(); + + ((MP4Integer16Property*)m_pProperties[1])->SetValue(1); + + // property reserved3 has non-zero fixed values + static uint8_t reserved3[14] = { + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, + }; + m_pProperties[5]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[5])-> + SetValue(reserved3, sizeof(reserved3)); + m_pProperties[5]->SetReadOnly(true); + + // property reserved4 has non-zero fixed values + static uint8_t reserved4[4] = { + 0x00, 0x18, 0xFF, 0xFF, + }; + m_pProperties[7]->SetReadOnly(false); + ((MP4BytesProperty*)m_pProperties[7])-> + SetValue(reserved4, sizeof(reserved4)); + m_pProperties[7]->SetReadOnly(true); +} + +/////////////////////////////////////////////////////////////////////////////// + +} +} // namespace mp4v2::impl diff --git a/src/atoms.h b/src/atoms.h index 382706f..9fd106b 100644 --- a/src/atoms.h +++ b/src/atoms.h @@ -178,6 +178,93 @@ class MP4AvcCAtom : public MP4Atom { MP4AvcCAtom &operator= ( const MP4AvcCAtom &src ); }; +// Opus https://www.opus-codec.org/docs/opus_in_isobmff.html + +class MP4OpusAtom : public MP4Atom { +public: + MP4OpusAtom(MP4File &file); + void Generate(); +private: + MP4OpusAtom(); + MP4OpusAtom( const MP4OpusAtom &src ); + MP4OpusAtom &operator= ( const MP4OpusAtom &src ); +}; + +class MP4DOpsAtom : public MP4Atom { +public: + MP4DOpsAtom(MP4File &file); + void Generate(); +private: + MP4DOpsAtom(); + MP4DOpsAtom( const MP4DOpsAtom &src ); + MP4DOpsAtom &operator= ( const MP4DOpsAtom &src ); +}; + +// https://aomediacodec.github.io/av1-isobmff/ + +class MP4Av01Atom : public MP4Atom { +public: + MP4Av01Atom(MP4File& file); + void Generate(); +private: + MP4Av01Atom(); + MP4Av01Atom(const MP4Av01Atom& src); + MP4Av01Atom& operator= (const MP4Av01Atom& src); +}; + +class MP4Av1CAtom : public MP4Atom { +public: + MP4Av1CAtom(MP4File& file); + void Generate(); +private: + MP4Av1CAtom(); + MP4Av1CAtom(const MP4Av1CAtom& src); + MP4Av1CAtom& operator= (const MP4Av1CAtom& src); +}; + + +// VPXX atoms https://storage.googleapis.com/downloads.webmproject.org/docs/vp9/vp-codec-iso-media-file-format-binding-20160516-draft.pdf + +class MP4Vp08Atom : public MP4Atom { +public: + MP4Vp08Atom(MP4File &file); + void Generate(); +private: + MP4Vp08Atom(); + MP4Vp08Atom( const MP4Vp08Atom &src ); + MP4Vp08Atom &operator= ( const MP4Vp08Atom &src ); +}; + +class MP4Vp09Atom : public MP4Atom { +public: + MP4Vp09Atom(MP4File &file); + void Generate(); +private: + MP4Vp09Atom(); + MP4Vp09Atom( const MP4Vp09Atom &src ); + MP4Vp09Atom &operator= ( const MP4Vp09Atom &src ); +}; + +class MP4Vp10Atom : public MP4Atom { +public: + MP4Vp10Atom(MP4File &file); + void Generate(); +private: + MP4Vp10Atom(); + MP4Vp10Atom( const MP4Vp10Atom &src ); + MP4Vp10Atom &operator= ( const MP4Vp10Atom &src ); +}; + +class MP4VpcCAtom : public MP4FullAtom { +public: + MP4VpcCAtom(MP4File &file); + void Generate(); +private: + MP4VpcCAtom(); + MP4VpcCAtom( const MP4VpcCAtom &src ); + MP4VpcCAtom &operator= ( const MP4VpcCAtom &src ); +}; + class MP4D263Atom : public MP4Atom { public: diff --git a/src/mp4.cpp b/src/mp4.cpp index 1016f79..ab3b34a 100644 --- a/src/mp4.cpp +++ b/src/mp4.cpp @@ -817,6 +817,28 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file return MP4_INVALID_TRACK_ID; } + MP4TrackId MP4AddOpusAudioTrack( + MP4FileHandle hFile, + uint32_t timeScale, + uint16_t channelCount, + uint32_t samplingRate) + { + if (MP4_IS_VALID_FILE_HANDLE(hFile)) { + try { + return ((MP4File*)hFile)-> + AddOpusAudioTrack(timeScale,channelCount,samplingRate); + } + catch( Exception* x ) { + mp4v2::impl::log.errorf(*x); + delete x; + } + catch( ... ) { + mp4v2::impl::log.errorf( "%s: failed", __FUNCTION__ ); + } + } + return MP4_INVALID_TRACK_ID; + } + MP4TrackId MP4AddULawAudioTrack( MP4FileHandle hFile, uint32_t timeScale) @@ -896,7 +918,7 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file } catch (...) { - return MP4_INVALID_TRACK_ID; + return NULL; } } @@ -1189,6 +1211,83 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file return MP4_INVALID_TRACK_ID; } + MP4TrackId MP4AddAV1VideoTrack(MP4FileHandle hFile, + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height) + { + if (MP4_IS_VALID_FILE_HANDLE(hFile)) { + try { + MP4File* pFile = (MP4File*)hFile; + + return pFile->AddAV1VideoTrack(timeScale, + sampleDuration, + width, + height); + } + catch (Exception* x) { + mp4v2::impl::log.errorf(*x); + delete x; + } + catch (...) { + mp4v2::impl::log.errorf("%s: failed", __FUNCTION__); + } + } + return MP4_INVALID_TRACK_ID; + } + + MP4TrackId MP4AddVP8VideoTrack(MP4FileHandle hFile, + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height) + { + if (MP4_IS_VALID_FILE_HANDLE(hFile)) { + try { + MP4File *pFile = (MP4File *)hFile; + + return pFile->AddVP8VideoTrack(timeScale, + sampleDuration, + width, + height); + } + catch( Exception* x ) { + mp4v2::impl::log.errorf(*x); + delete x; + } + catch( ... ) { + mp4v2::impl::log.errorf( "%s: failed", __FUNCTION__ ); + } + } + return MP4_INVALID_TRACK_ID; + } + + MP4TrackId MP4AddVP9VideoTrack(MP4FileHandle hFile, + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height) + { + if (MP4_IS_VALID_FILE_HANDLE(hFile)) { + try { + MP4File *pFile = (MP4File *)hFile; + + return pFile->AddVP9VideoTrack(timeScale, + sampleDuration, + width, + height); + } + catch( Exception* x ) { + mp4v2::impl::log.errorf(*x); + delete x; + } + catch( ... ) { + mp4v2::impl::log.errorf( "%s: failed", __FUNCTION__ ); + } + } + return MP4_INVALID_TRACK_ID; + } MP4TrackId MP4AddH264VideoTrack(MP4FileHandle hFile, uint32_t timeScale, @@ -1315,6 +1414,31 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file } return; } + void MP4SetAv1SequenceObu( + MP4FileHandle hFile, + MP4TrackId trackId, + const uint8_t* pSequence, + uint16_t sequenceLen) + { + if (MP4_IS_VALID_FILE_HANDLE(hFile)) { + try { + MP4File* pFile = (MP4File*)hFile; + + pFile->SetAv1SequenceObu(trackId, + pSequence, + sequenceLen); + return; + } + catch (Exception* x) { + mp4v2::impl::log.errorf(*x); + delete x; + } + catch (...) { + mp4v2::impl::log.errorf("%s: failed", __FUNCTION__); + } + } + return; + } MP4TrackId MP4AddH263VideoTrack( MP4FileHandle hFile, diff --git a/src/mp4atom.cpp b/src/mp4atom.cpp index 520cbc8..59231c1 100644 --- a/src/mp4atom.cpp +++ b/src/mp4atom.cpp @@ -191,14 +191,14 @@ MP4Atom* MP4Atom::ReadAtom(MP4File& file, MP4Atom* pParentAtom) pAtom->SetParentAtom(pParentAtom); - try { - pAtom->Read(); - } - catch (Exception* x) { - // delete atom and rethrow so we don't leak memory. - delete pAtom; - throw x; - } + try { + pAtom->Read(); + } + catch (Exception* x) { + // delete atom and rethrow so we don't leak memory. + delete pAtom; + throw x; + } return pAtom; @@ -649,9 +649,11 @@ void MP4Atom::Dump(uint8_t indent, bool dumpImplicits) if( can.length() ) can.resize( can.length() - 1 ); - log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": type %s (%s)", + log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": type %s (%s) %d childs %d properties", GetFile().GetFilename().c_str(), - m_type, can.c_str() ); + m_type, can.c_str(), + m_pChildAtoms.Size(), + m_pProperties.Size()); } uint32_t i; @@ -808,6 +810,11 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type ) // no-context construction (old-style) switch( (uint8_t)type[0] ) { + case 'O': + if( ATOMID(type) == ATOMID("Opus") ) + return new MP4OpusAtom(file); + break; + case 'S': if( ATOMID(type) == ATOMID("SVQ3") ) return new MP4VideoAtom( file, type ); @@ -816,6 +823,10 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type ) break; case 'a': + if (ATOMID(type) == ATOMID("av01")) + return new MP4Av01Atom(file); + if (ATOMID(type) == ATOMID("av1C")) + return new MP4Av1CAtom(file); if( ATOMID(type) == ATOMID("avc1") ) return new MP4Avc1Atom(file); if( ATOMID(type) == ATOMID("ac-3") ) @@ -850,6 +861,8 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type ) return new MP4TrefTypeAtom( file, type ); if( ATOMID(type) == ATOMID("dac3") ) return new MP4DAc3Atom(file); + if( ATOMID(type) == ATOMID("dOps") ) + return new MP4DOpsAtom(file); break; case 'e': @@ -997,6 +1010,15 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type ) case 'v': if( ATOMID(type) == ATOMID("vmhd") ) return new MP4VmhdAtom(file); + if( ATOMID(type) == ATOMID("vp08") ) + return new MP4Vp08Atom(file); + if( ATOMID(type) == ATOMID("vp09") ) + return new MP4Vp09Atom(file); + if( ATOMID(type) == ATOMID("vp10") ) + return new MP4Vp10Atom(file); + if( ATOMID(type) == ATOMID("vpcC") ) + return new MP4VpcCAtom(file); + break; case 'y': diff --git a/src/mp4file.cpp b/src/mp4file.cpp index 86f386b..d023716 100644 --- a/src/mp4file.cpp +++ b/src/mp4file.cpp @@ -1304,6 +1304,43 @@ MP4TrackId MP4File::AddAmrAudioTrack( return trackId; } +MP4TrackId MP4File::AddOpusAudioTrack(uint32_t timeScale, uint16_t channelCount,uint32_t samplingRate) +{ + + uint32_t fixedSampleDuration = (timeScale * 20)/1000; // 20mSec/Sample + + MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale); + + AddTrackToOd(trackId); + + SetTrackFloatProperty(trackId, "tkhd.volume", 1.0); + + (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0); + + (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "Opus"); + + // stsd is a unique beast in that it has a count of the number + // of child atoms that needs to be incremented after we add the mp4a atom + MP4Integer32Property* pStsdCountProperty; + FindIntegerProperty( + MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"), + (MP4Property**)&pStsdCountProperty); + pStsdCountProperty->IncrementValue(); + + SetTrackIntegerProperty(trackId, + "mdia.minf.stbl.stsd.Opus.channelCount", + channelCount); + + SetTrackIntegerProperty(trackId, + "mdia.minf.stbl.stsd.Opus.samplingRate", + samplingRate<<16); + + m_pTracks[FindTrackIndex(trackId)]->SetFixedSampleDuration(fixedSampleDuration); + + return trackId; +} + + MP4TrackId MP4File::AddULawAudioTrack( uint32_t timeScale) { uint32_t fixedSampleDuration = (timeScale * 20)/1000; // 20mSec/Sample @@ -1838,6 +1875,66 @@ MP4TrackId MP4File::AddH264VideoTrack( return trackId; } +MP4TrackId MP4File::AddAV1VideoTrack( + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height) +{ + MP4TrackId trackId = AddVideoTrackDefault(timeScale, + sampleDuration, + width, + height, + "av01"); + + SetTrackIntegerProperty(trackId, + "mdia.minf.stbl.stsd.av01.width", width); + SetTrackIntegerProperty(trackId, + "mdia.minf.stbl.stsd.av01.height", height); + + return trackId; +} + +MP4TrackId MP4File::AddVP8VideoTrack( + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height) +{ + MP4TrackId trackId = AddVideoTrackDefault(timeScale, + sampleDuration, + width, + height, + "vp08"); + + SetTrackIntegerProperty(trackId, + "mdia.minf.stbl.stsd.vp08.width", width); + SetTrackIntegerProperty(trackId, + "mdia.minf.stbl.stsd.vp08.height", height); + + return trackId; +} + +MP4TrackId MP4File::AddVP9VideoTrack( + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height) +{ + MP4TrackId trackId = AddVideoTrackDefault(timeScale, + sampleDuration, + width, + height, + "vp09"); + + SetTrackIntegerProperty(trackId, + "mdia.minf.stbl.stsd.vp09.width", width); + SetTrackIntegerProperty(trackId, + "mdia.minf.stbl.stsd.vp09.height", height); + + return trackId; +} + MP4TrackId MP4File::AddEncH264VideoTrack( uint32_t timeScale, MP4Duration sampleDuration, @@ -2008,6 +2105,27 @@ void MP4File::AddH264PictureParameterSet (MP4TrackId trackId, return; } + +void MP4File::SetAv1SequenceObu(MP4TrackId trackId, + const uint8_t* pSequence, + uint16_t sequenceLen) +{ + MP4Atom* av1CAtom = + FindAtom(MakeTrackName(trackId, + "mdia.minf.stbl.stsd.av01.av1C")); + MP4BytesProperty* pUnit; + if (av1CAtom->FindProperty("av1C.configOBUs", + (MP4Property**)&pUnit) == false) { + log.errorf("%s: \"%s\": Could not find av1C configOBUs properties", + __FUNCTION__, GetFilename().c_str()); + return; + } + + pUnit->SetValue(pSequence, sequenceLen); + + return; +} + void MP4File::SetH263Vendor( MP4TrackId trackId, uint32_t vendor) diff --git a/src/mp4file.h b/src/mp4file.h index 960505e..168fbeb 100644 --- a/src/mp4file.h +++ b/src/mp4file.h @@ -247,11 +247,16 @@ class MP4File uint32_t timeScale, MP4Duration sampleDuration, uint8_t audioType); - + + MP4TrackId AddOpusAudioTrack( + uint32_t timeScale, + uint16_t channelCount, + uint32_t samplingRate); + MP4TrackId AddULawAudioTrack( uint32_t timeScale); - MP4TrackId AddALawAudioTrack( + MP4TrackId AddALawAudioTrack( uint32_t timeScale); MP4TrackId AddAC3AudioTrack( @@ -338,6 +343,24 @@ class MP4File uint32_t avgBitrate, uint32_t maxBitrate); + MP4TrackId AddAV1VideoTrack( + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height); + + MP4TrackId AddVP8VideoTrack( + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height); + + MP4TrackId AddVP9VideoTrack( + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height); + MP4TrackId AddH264VideoTrack( uint32_t timeScale, MP4Duration sampleDuration, @@ -362,6 +385,9 @@ class MP4File void AddH264PictureParameterSet(MP4TrackId trackId, const uint8_t *pPicture, uint16_t pictureLen); + void SetAv1SequenceObu(MP4TrackId trackId, + const uint8_t* pSequence, + uint16_t sequenceLen); MP4TrackId AddHintTrack(MP4TrackId refTrackId); MP4TrackId AddTextTrack(MP4TrackId refTrackId); diff --git a/src/mp4info.cpp b/src/mp4info.cpp index 676a5be..5c1d2ff 100644 --- a/src/mp4info.cpp +++ b/src/mp4info.cpp @@ -287,6 +287,9 @@ static char* PrintVideoInfo( MP4_YUV12_VIDEO_TYPE, MP4_H263_VIDEO_TYPE, MP4_H261_VIDEO_TYPE, + MP4_VP8_VIDEO_TYPE, + MP4_VP9_VIDEO_TYPE, + MP4_AV1_VIDEO_TYPE, }; static const char* mpegVideoNames[] = { "MPEG-2 Simple", @@ -300,6 +303,9 @@ static char* PrintVideoInfo( "YUV12", "H.263", "H.261", + "VP8", + "VP9", + "AV1", }; uint8_t numMpegVideoTypes = sizeof(mpegVideoTypes) / sizeof(uint8_t); @@ -389,6 +395,12 @@ static char* PrintVideoInfo( // 3gp h.263 typeName = "H.263"; foundTypeName = true; + } else if (strcasecmp(media_data_name, "vp08") == 0) { + typeName = "VP8"; + foundTypeName = true; + } else if (strcasecmp(media_data_name, "vp09") == 0) { + typeName = "VP9"; + foundTypeName = true; } else if ((strcasecmp(media_data_name, "mp4v") == 0) || (strcasecmp(media_data_name, "encv") == 0)) { // note encv might needs it's own field eventually. diff --git a/src/mp4util.h b/src/mp4util.h index 1fbbd81..b33bb44 100644 --- a/src/mp4util.h +++ b/src/mp4util.h @@ -33,7 +33,7 @@ namespace mp4v2 { namespace impl { #ifndef ASSERT # define ASSERT(expr) \ if (!(expr)) { \ - throw new Exception("assert failure: "LIBMPV42_STRINGIFY((expr)), __FILE__, __LINE__, __FUNCTION__ ); \ + throw new Exception("assert failure: " LIBMPV42_STRINGIFY((expr)), __FILE__, __LINE__, __FUNCTION__ ); \ } #endif diff --git a/src/rtphint.cpp b/src/rtphint.cpp index e07309d..1eb01f5 100644 --- a/src/rtphint.cpp +++ b/src/rtphint.cpp @@ -339,7 +339,7 @@ void MP4RtpHintTrack::GetPayload( pSlash = strchr(pSlash, '/'); if (pSlash != NULL) { pSlash++; - if (pSlash != '\0') { + if (*pSlash != '\0') { length = (uint32_t)strlen(pRtpMap) - (pSlash - pRtpMap); *ppEncodingParams = (char *)MP4Calloc(length + 1); strncpy(*ppEncodingParams, pSlash, length);