From 9287d02d2551c8013c0d39e0e9662d1b2f91fe6f Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Fri, 4 Nov 2016 17:39:09 +0100 Subject: [PATCH 01/11] Added MP4AddVP8VideoTrack --- GNUmakefile.am | 2 ++ include/mp4v2/general.h | 1 + include/mp4v2/track.h | 8 ++++++++ src/atoms.h | 42 +++++++++++++++++++++++++++++++++++++++++ src/mp4.cpp | 25 ++++++++++++++++++++++++ src/mp4atom.cpp | 14 ++++++++++++-- src/mp4file.cpp | 20 ++++++++++++++++++++ src/mp4file.h | 6 ++++++ src/mp4info.cpp | 5 +++++ 9 files changed, 121 insertions(+), 2 deletions(-) diff --git a/GNUmakefile.am b/GNUmakefile.am index 947e6e3..a833f49 100644 --- a/GNUmakefile.am +++ b/GNUmakefile.am @@ -16,6 +16,8 @@ libmp4v2_la_SOURCES = \ src/atom_amr.cpp \ src/atom_avc1.cpp \ src/atom_avcC.cpp \ + src/atom_vpxx.cpp \ + src/atom_pvcC.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..36b1cc3 100644 --- a/include/mp4v2/general.h +++ b/include/mp4v2/general.h @@ -184,6 +184,7 @@ 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 */ /* 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..fdbf076 100644 --- a/include/mp4v2/track.h +++ b/include/mp4v2/track.h @@ -246,6 +246,14 @@ MP4TrackId MP4AddVideoTrack( uint16_t height, uint8_t videoType DEFAULT(MP4_MPEG4_VIDEO_TYPE) ); +MP4V2_EXPORT +MP4TrackId MP4AddVP8VideoTrack( + MP4FileHandle hFile, + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height ); + MP4V2_EXPORT MP4TrackId MP4AddH264VideoTrack( MP4FileHandle hFile, diff --git a/src/atoms.h b/src/atoms.h index 382706f..f3c2ba5 100644 --- a/src/atoms.h +++ b/src/atoms.h @@ -178,6 +178,48 @@ class MP4AvcCAtom : public MP4Atom { MP4AvcCAtom &operator= ( const MP4AvcCAtom &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 MP4PvcCAtom : public MP4Atom { +public: + MP4PvcCAtom(MP4File &file); + void Generate(); +private: + MP4PvcCAtom(); + MP4PvcCAtom( const MP4PvcCAtom &src ); + MP4PvcCAtom &operator= ( const MP4PvcCAtom &src ); +}; + class MP4D263Atom : public MP4Atom { public: diff --git a/src/mp4.cpp b/src/mp4.cpp index 1016f79..36c80b1 100644 --- a/src/mp4.cpp +++ b/src/mp4.cpp @@ -1189,6 +1189,31 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file 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 MP4AddH264VideoTrack(MP4FileHandle hFile, uint32_t timeScale, diff --git a/src/mp4atom.cpp b/src/mp4atom.cpp index 520cbc8..a072f18 100644 --- a/src/mp4atom.cpp +++ b/src/mp4atom.cpp @@ -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; @@ -928,6 +930,8 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type ) case 'p': if( ATOMID(type) == ATOMID("pasp") ) return new MP4PaspAtom(file); + if( ATOMID(type) == ATOMID("pvcC") ) + return new MP4PvcCAtom(file); break; case 'r': @@ -997,6 +1001,12 @@ 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); break; case 'y': diff --git a/src/mp4file.cpp b/src/mp4file.cpp index 86f386b..fc3b5d6 100644 --- a/src/mp4file.cpp +++ b/src/mp4file.cpp @@ -1838,6 +1838,26 @@ MP4TrackId MP4File::AddH264VideoTrack( 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::AddEncH264VideoTrack( uint32_t timeScale, MP4Duration sampleDuration, diff --git a/src/mp4file.h b/src/mp4file.h index 960505e..3ba76d8 100644 --- a/src/mp4file.h +++ b/src/mp4file.h @@ -337,6 +337,12 @@ class MP4File uint8_t h263Profile, uint32_t avgBitrate, uint32_t maxBitrate); + + MP4TrackId AddVP8VideoTrack( + uint32_t timeScale, + MP4Duration sampleDuration, + uint16_t width, + uint16_t height); MP4TrackId AddH264VideoTrack( uint32_t timeScale, diff --git a/src/mp4info.cpp b/src/mp4info.cpp index 676a5be..504937f 100644 --- a/src/mp4info.cpp +++ b/src/mp4info.cpp @@ -287,6 +287,7 @@ static char* PrintVideoInfo( MP4_YUV12_VIDEO_TYPE, MP4_H263_VIDEO_TYPE, MP4_H261_VIDEO_TYPE, + MP4_VP8_VIDEO_TYPE, }; static const char* mpegVideoNames[] = { "MPEG-2 Simple", @@ -300,6 +301,7 @@ static char* PrintVideoInfo( "YUV12", "H.263", "H.261", + "VP8", }; uint8_t numMpegVideoTypes = sizeof(mpegVideoTypes) / sizeof(uint8_t); @@ -389,6 +391,9 @@ 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, "mp4v") == 0) || (strcasecmp(media_data_name, "encv") == 0)) { // note encv might needs it's own field eventually. From febe30853901a6e861800fc833a7408a2f4220e8 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Fri, 4 Nov 2016 18:56:49 +0100 Subject: [PATCH 02/11] Add vp8 atoms --- src/atom_pvcC.cpp | 60 +++++++++++++ src/atom_vpxx.cpp | 211 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 271 insertions(+) create mode 100644 src/atom_pvcC.cpp create mode 100644 src/atom_vpxx.cpp diff --git a/src/atom_pvcC.cpp b/src/atom_pvcC.cpp new file mode 100644 index 0000000..d6d3959 --- /dev/null +++ b/src/atom_pvcC.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 { + +/////////////////////////////////////////////////////////////////////////////// + +MP4PvcCAtom::MP4PvcCAtom(MP4File &file) + : MP4Atom(file, "pvcC") +{ + + 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 MP4PvcCAtom::Generate() +{ + MP4Atom::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])->SetCount(0); +} +/////////////////////////////////////////////////////////////////////////////// + +} +} // namespace mp4v2::impl diff --git a/src/atom_vpxx.cpp b/src/atom_vpxx.cpp new file mode 100644 index 0000000..6e4b01b --- /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("pvcC", 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("pvcC", 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("pvcC", 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 From 9c10ab4a749a7f72ea2a9d3d8fb38dc61c361e1b Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Sun, 6 Nov 2016 21:34:13 +0100 Subject: [PATCH 03/11] Add MP4AddOpusAudioTrack and opus atoms --- GNUmakefile.am | 4 +- include/mp4v2/general.h | 1 + include/mp4v2/track.h | 7 +++ libplatform/config.h.in | 3 +- src/atom_dops.cpp | 54 +++++++++++++++++++++ src/atom_opus.cpp | 70 ++++++++++++++++++++++++++++ src/{atom_pvcC.cpp => atom_vpcC.cpp} | 10 ++-- src/atom_vpxx.cpp | 6 +-- src/atoms.h | 32 +++++++++++-- src/mp4.cpp | 22 +++++++++ src/mp4atom.cpp | 9 +++- src/mp4file.cpp | 37 +++++++++++++++ src/mp4file.h | 9 +++- 13 files changed, 244 insertions(+), 20 deletions(-) create mode 100644 src/atom_dops.cpp create mode 100644 src/atom_opus.cpp rename src/{atom_pvcC.cpp => atom_vpcC.cpp} (91%) diff --git a/GNUmakefile.am b/GNUmakefile.am index a833f49..5f95307 100644 --- a/GNUmakefile.am +++ b/GNUmakefile.am @@ -17,7 +17,9 @@ libmp4v2_la_SOURCES = \ src/atom_avc1.cpp \ src/atom_avcC.cpp \ src/atom_vpxx.cpp \ - src/atom_pvcC.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 36b1cc3..cf2e47c 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 diff --git a/include/mp4v2/track.h b/include/mp4v2/track.h index fdbf076..155a6b2 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() 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/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_pvcC.cpp b/src/atom_vpcC.cpp similarity index 91% rename from src/atom_pvcC.cpp rename to src/atom_vpcC.cpp index d6d3959..b8f51f8 100644 --- a/src/atom_pvcC.cpp +++ b/src/atom_vpcC.cpp @@ -26,8 +26,8 @@ namespace impl { /////////////////////////////////////////////////////////////////////////////// -MP4PvcCAtom::MP4PvcCAtom(MP4File &file) - : MP4Atom(file, "pvcC") +MP4VpcCAtom::MP4VpcCAtom(MP4File &file) + : MP4FullAtom(file, "vpcC") { AddProperty( new MP4Integer8Property(*this,"profile")); /* 0 */ @@ -41,9 +41,9 @@ MP4PvcCAtom::MP4PvcCAtom(MP4File &file) AddProperty( new MP4BytesProperty(*this,"codecIntializationData",0)); /* 8 */ } -void MP4PvcCAtom::Generate() +void MP4VpcCAtom::Generate() { - MP4Atom::Generate(); + MP4FullAtom::Generate(); ((MP4Integer8Property*)m_pProperties[0])->SetValue(0); ((MP4Integer8Property*)m_pProperties[1])->SetValue(0); ((MP4BitfieldProperty*)m_pProperties[2])->SetValue(0); @@ -52,7 +52,7 @@ void MP4PvcCAtom::Generate() ((MP4BitfieldProperty*)m_pProperties[5])->SetValue(0); ((MP4BitfieldProperty*)m_pProperties[6])->SetValue(0); ((MP4Integer16Property*)m_pProperties[7])->SetValue(0); - ((MP4BytesProperty*)m_pProperties[8])->SetCount(0); + //((MP4BytesProperty*)m_pProperties[8])->SetValueSize(0,0); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/atom_vpxx.cpp b/src/atom_vpxx.cpp index 6e4b01b..20db568 100644 --- a/src/atom_vpxx.cpp +++ b/src/atom_vpxx.cpp @@ -52,7 +52,7 @@ MP4Vp08Atom::MP4Vp08Atom(MP4File &file) AddReserved(*this, "reserved4", 4); /* 7 */ - ExpectChildAtom("pvcC", Required, OnlyOne); + ExpectChildAtom("vpcC", Required, OnlyOne); } void MP4Vp08Atom::Generate() @@ -113,7 +113,7 @@ MP4Vp09Atom::MP4Vp09Atom(MP4File &file) AddReserved(*this, "reserved4", 4); /* 7 */ - ExpectChildAtom("pvcC", Required, OnlyOne); + ExpectChildAtom("vpcC", Required, OnlyOne); } void MP4Vp09Atom::Generate() @@ -174,7 +174,7 @@ MP4Vp10Atom::MP4Vp10Atom(MP4File &file) AddReserved(*this, "reserved4", 4); /* 7 */ - ExpectChildAtom("pvcC", Required, OnlyOne); + ExpectChildAtom("vpcC", Required, OnlyOne); } void MP4Vp10Atom::Generate() diff --git a/src/atoms.h b/src/atoms.h index f3c2ba5..9e58782 100644 --- a/src/atoms.h +++ b/src/atoms.h @@ -178,6 +178,28 @@ 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 ); +}; + // 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 { @@ -210,14 +232,14 @@ class MP4Vp10Atom : public MP4Atom { MP4Vp10Atom &operator= ( const MP4Vp10Atom &src ); }; -class MP4PvcCAtom : public MP4Atom { +class MP4VpcCAtom : public MP4FullAtom { public: - MP4PvcCAtom(MP4File &file); + MP4VpcCAtom(MP4File &file); void Generate(); private: - MP4PvcCAtom(); - MP4PvcCAtom( const MP4PvcCAtom &src ); - MP4PvcCAtom &operator= ( const MP4PvcCAtom &src ); + MP4VpcCAtom(); + MP4VpcCAtom( const MP4VpcCAtom &src ); + MP4VpcCAtom &operator= ( const MP4VpcCAtom &src ); }; diff --git a/src/mp4.cpp b/src/mp4.cpp index 36c80b1..13e9a45 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) diff --git a/src/mp4atom.cpp b/src/mp4atom.cpp index a072f18..77a0564 100644 --- a/src/mp4atom.cpp +++ b/src/mp4atom.cpp @@ -925,13 +925,15 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type ) case 'o': if( ATOMID(type) == ATOMID("ohdr") ) return new MP4OhdrAtom(file); + if( ATOMID(type) == ATOMID("Opus") ) + return new MP4OpusAtom(file); + if( ATOMID(type) == ATOMID("dOps") ) + return new MP4DOpsAtom(file); break; case 'p': if( ATOMID(type) == ATOMID("pasp") ) return new MP4PaspAtom(file); - if( ATOMID(type) == ATOMID("pvcC") ) - return new MP4PvcCAtom(file); break; case 'r': @@ -1007,6 +1009,9 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type ) 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 fc3b5d6..e202b37 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 diff --git a/src/mp4file.h b/src/mp4file.h index 3ba76d8..a498e09 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( From dc8d8623d6d4be6224690a1712da4b7324a77f62 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Tue, 8 Nov 2016 12:07:48 +0100 Subject: [PATCH 04/11] Fix atom factory for Opus --- src/mp4atom.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/mp4atom.cpp b/src/mp4atom.cpp index 77a0564..a8b43d4 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; @@ -810,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 ); @@ -852,6 +857,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': @@ -925,10 +932,6 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type ) case 'o': if( ATOMID(type) == ATOMID("ohdr") ) return new MP4OhdrAtom(file); - if( ATOMID(type) == ATOMID("Opus") ) - return new MP4OpusAtom(file); - if( ATOMID(type) == ATOMID("dOps") ) - return new MP4DOpsAtom(file); break; case 'p': From 94b17cb39c9834bebe33f087ee06655e1ee9e462 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Thu, 28 Dec 2017 18:30:16 +0800 Subject: [PATCH 05/11] Fix trivial errors --- src/mp4.cpp | 2 +- src/rtphint.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mp4.cpp b/src/mp4.cpp index 13e9a45..3e5645e 100644 --- a/src/mp4.cpp +++ b/src/mp4.cpp @@ -918,7 +918,7 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file } catch (...) { - return MP4_INVALID_TRACK_ID; + return NULL; } } 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); From e2822f28cc74957573a71cc7e2c26ce7e7867e66 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Fri, 2 Feb 2018 13:28:05 +0100 Subject: [PATCH 06/11] Add VP9 support --- include/mp4v2/general.h | 1 + include/mp4v2/track.h | 8 ++++++++ src/mp4.cpp | 28 +++++++++++++++++++++++++++- src/mp4file.cpp | 20 ++++++++++++++++++++ src/mp4file.h | 6 ++++++ src/mp4info.cpp | 5 +++++ 6 files changed, 67 insertions(+), 1 deletion(-) diff --git a/include/mp4v2/general.h b/include/mp4v2/general.h index cf2e47c..76e0572 100644 --- a/include/mp4v2/general.h +++ b/include/mp4v2/general.h @@ -186,6 +186,7 @@ typedef uint32_t (*encryptFunc_t)( uint32_t, uint32_t, uint8_t*, uint32_t*, uint #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 */ /* MP4 Video type utilities */ #define MP4_IS_MPEG1_VIDEO_TYPE(type) \ diff --git a/include/mp4v2/track.h b/include/mp4v2/track.h index 155a6b2..c1285fb 100644 --- a/include/mp4v2/track.h +++ b/include/mp4v2/track.h @@ -261,6 +261,14 @@ MP4TrackId MP4AddVP8VideoTrack( 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, diff --git a/src/mp4.cpp b/src/mp4.cpp index 3e5645e..81aadb1 100644 --- a/src/mp4.cpp +++ b/src/mp4.cpp @@ -1211,7 +1211,7 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file return MP4_INVALID_TRACK_ID; } - MP4TrackId MP4AddVP8VideoTrack(MP4FileHandle hFile, + MP4TrackId MP4AddVP8VideoTrack(MP4FileHandle hFile, uint32_t timeScale, MP4Duration sampleDuration, uint16_t width, @@ -1237,6 +1237,32 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file 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, MP4Duration sampleDuration, diff --git a/src/mp4file.cpp b/src/mp4file.cpp index e202b37..48df4d4 100644 --- a/src/mp4file.cpp +++ b/src/mp4file.cpp @@ -1895,6 +1895,26 @@ MP4TrackId MP4File::AddVP8VideoTrack( 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, diff --git a/src/mp4file.h b/src/mp4file.h index a498e09..bf67111 100644 --- a/src/mp4file.h +++ b/src/mp4file.h @@ -349,6 +349,12 @@ class MP4File 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, diff --git a/src/mp4info.cpp b/src/mp4info.cpp index 504937f..cf434dd 100644 --- a/src/mp4info.cpp +++ b/src/mp4info.cpp @@ -288,6 +288,7 @@ static char* PrintVideoInfo( MP4_H263_VIDEO_TYPE, MP4_H261_VIDEO_TYPE, MP4_VP8_VIDEO_TYPE, + MP4_VP9_VIDEO_TYPE, }; static const char* mpegVideoNames[] = { "MPEG-2 Simple", @@ -302,6 +303,7 @@ static char* PrintVideoInfo( "H.263", "H.261", "VP8", + "VP9", }; uint8_t numMpegVideoTypes = sizeof(mpegVideoTypes) / sizeof(uint8_t); @@ -394,6 +396,9 @@ static char* PrintVideoInfo( } 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. From 8488fca7a0c820bac08c1662f20aadd7a7cfc584 Mon Sep 17 00:00:00 2001 From: ZitaLiao Date: Thu, 28 Sep 2023 01:10:53 +1000 Subject: [PATCH 07/11] Add CMakefile (#1) --- CMakeLists.txt | 258 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100755 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..538dab2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,258 @@ +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_avc1.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atom_avcC.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) + From 918c7eb28df1a7fee2f961892d9fadfd47dc36dc Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Fri, 6 Oct 2023 10:18:56 +0200 Subject: [PATCH 08/11] Fix compilation warning --- src/mp4util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 333fe08315812225aaea8171fbfcc926e984341b Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Fri, 6 Oct 2023 10:22:49 +0200 Subject: [PATCH 09/11] Fix narrowing compilation warning --- libutil/Utility.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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; From 92fe4d26cd77f32bebc64f2a0a62b71fd1ff84f4 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Thu, 18 Jul 2024 11:29:27 +0200 Subject: [PATCH 10/11] Add AV1 support --- CMakeLists.txt | 2 + GNUmakefile.am | 2 + include/mp4v2/general.h | 1 + include/mp4v2/track.h | 8 ++++ src/atom_av1C.cpp | 73 +++++++++++++++++++++++++++++++++ src/atom_avxx.cpp | 89 +++++++++++++++++++++++++++++++++++++++++ src/atoms.h | 23 +++++++++++ src/mp4.cpp | 26 ++++++++++++ src/mp4atom.cpp | 4 ++ src/mp4file.cpp | 20 +++++++++ src/mp4file.h | 8 +++- src/mp4info.cpp | 2 + 12 files changed, 257 insertions(+), 1 deletion(-) mode change 100755 => 100644 CMakeLists.txt create mode 100644 src/atom_av1C.cpp create mode 100644 src/atom_avxx.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index 538dab2..cb200fe --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,8 +122,10 @@ set(SOURCE_FILES ${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 diff --git a/GNUmakefile.am b/GNUmakefile.am index 5f95307..4bf55a6 100644 --- a/GNUmakefile.am +++ b/GNUmakefile.am @@ -14,8 +14,10 @@ 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 \ diff --git a/include/mp4v2/general.h b/include/mp4v2/general.h index 76e0572..9d0caa2 100644 --- a/include/mp4v2/general.h +++ b/include/mp4v2/general.h @@ -187,6 +187,7 @@ typedef uint32_t (*encryptFunc_t)( uint32_t, uint32_t, uint8_t*, uint32_t*, uint #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 c1285fb..60f6c3a 100644 --- a/include/mp4v2/track.h +++ b/include/mp4v2/track.h @@ -253,6 +253,14 @@ 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, diff --git a/src/atom_av1C.cpp b/src/atom_av1C.cpp new file mode 100644 index 0000000..765c963 --- /dev/null +++ b/src/atom_av1C.cpp @@ -0,0 +1,73 @@ +/* + * 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) + : MP4FullAtom(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() +{ + MP4FullAtom::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); + //((MP4BytesProperty*)m_pProperties[8])->SetValueSize(0,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/atoms.h b/src/atoms.h index 9e58782..58b2b35 100644 --- a/src/atoms.h +++ b/src/atoms.h @@ -200,6 +200,29 @@ class MP4DOpsAtom : public MP4Atom { 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 MP4FullAtom { +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 { diff --git a/src/mp4.cpp b/src/mp4.cpp index 81aadb1..cfcf291 100644 --- a/src/mp4.cpp +++ b/src/mp4.cpp @@ -1211,6 +1211,32 @@ 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, diff --git a/src/mp4atom.cpp b/src/mp4atom.cpp index a8b43d4..59231c1 100644 --- a/src/mp4atom.cpp +++ b/src/mp4atom.cpp @@ -823,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") ) diff --git a/src/mp4file.cpp b/src/mp4file.cpp index 48df4d4..cc88fd9 100644 --- a/src/mp4file.cpp +++ b/src/mp4file.cpp @@ -1875,6 +1875,26 @@ 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, diff --git a/src/mp4file.h b/src/mp4file.h index bf67111..e9bc12d 100644 --- a/src/mp4file.h +++ b/src/mp4file.h @@ -342,7 +342,13 @@ class MP4File uint8_t h263Profile, 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, diff --git a/src/mp4info.cpp b/src/mp4info.cpp index cf434dd..5c1d2ff 100644 --- a/src/mp4info.cpp +++ b/src/mp4info.cpp @@ -289,6 +289,7 @@ static char* PrintVideoInfo( MP4_H261_VIDEO_TYPE, MP4_VP8_VIDEO_TYPE, MP4_VP9_VIDEO_TYPE, + MP4_AV1_VIDEO_TYPE, }; static const char* mpegVideoNames[] = { "MPEG-2 Simple", @@ -304,6 +305,7 @@ static char* PrintVideoInfo( "H.261", "VP8", "VP9", + "AV1", }; uint8_t numMpegVideoTypes = sizeof(mpegVideoTypes) / sizeof(uint8_t); From e81dd7f22e577cf4a84412f7c23bd8331f88b7b4 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Fri, 19 Jul 2024 10:18:48 +0200 Subject: [PATCH 11/11] Fix av1C and add MP4SetAv1SequenceObu --- include/mp4v2/track.h | 8 ++++++++ src/atom_av1C.cpp | 8 +++----- src/atoms.h | 2 +- src/mp4.cpp | 25 +++++++++++++++++++++++++ src/mp4file.cpp | 21 +++++++++++++++++++++ src/mp4file.h | 3 +++ 6 files changed, 61 insertions(+), 6 deletions(-) diff --git a/include/mp4v2/track.h b/include/mp4v2/track.h index 60f6c3a..80b0bd3 100644 --- a/include/mp4v2/track.h +++ b/include/mp4v2/track.h @@ -303,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/src/atom_av1C.cpp b/src/atom_av1C.cpp index 765c963..1050750 100644 --- a/src/atom_av1C.cpp +++ b/src/atom_av1C.cpp @@ -27,12 +27,11 @@ namespace impl { /////////////////////////////////////////////////////////////////////////////// MP4Av1CAtom::MP4Av1CAtom(MP4File &file) - : MP4FullAtom(file, "av1C") + : 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_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 */ @@ -50,7 +49,7 @@ MP4Av1CAtom::MP4Av1CAtom(MP4File &file) void MP4Av1CAtom::Generate() { - MP4FullAtom::Generate(); + MP4Atom::Generate(); ((MP4BitfieldProperty*)m_pProperties[0])->SetValue(1); ((MP4BitfieldProperty*)m_pProperties[1])->SetValue(1); ((MP4BitfieldProperty*)m_pProperties[2])->SetValue(0); @@ -65,7 +64,6 @@ void MP4Av1CAtom::Generate() ((MP4BitfieldProperty*)m_pProperties[11])->SetValue(0); ((MP4BitfieldProperty*)m_pProperties[12])->SetValue(0); ((MP4BitfieldProperty*)m_pProperties[13])->SetValue(0); - //((MP4BytesProperty*)m_pProperties[8])->SetValueSize(0,0); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/atoms.h b/src/atoms.h index 58b2b35..9fd106b 100644 --- a/src/atoms.h +++ b/src/atoms.h @@ -212,7 +212,7 @@ class MP4Av01Atom : public MP4Atom { MP4Av01Atom& operator= (const MP4Av01Atom& src); }; -class MP4Av1CAtom : public MP4FullAtom { +class MP4Av1CAtom : public MP4Atom { public: MP4Av1CAtom(MP4File& file); void Generate(); diff --git a/src/mp4.cpp b/src/mp4.cpp index cfcf291..ab3b34a 100644 --- a/src/mp4.cpp +++ b/src/mp4.cpp @@ -1414,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/mp4file.cpp b/src/mp4file.cpp index cc88fd9..d023716 100644 --- a/src/mp4file.cpp +++ b/src/mp4file.cpp @@ -2105,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 e9bc12d..168fbeb 100644 --- a/src/mp4file.h +++ b/src/mp4file.h @@ -385,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);