diff options
author | Spec-Chum <spec-chum@users.sourceforge.net> | 2010-01-01 22:16:07 +0300 |
---|---|---|
committer | Spec-Chum <spec-chum@users.sourceforge.net> | 2010-01-01 22:16:07 +0300 |
commit | e6614272516c4582a1fcf01b5773e379809b86b5 (patch) | |
tree | e562a85b0361205508e596d6342c2e1c8d59e9aa /src/filters/parser | |
parent | e903fa492b27da8d505057b1722dbb35e2ec47e4 (diff) |
Added missing files from Ap4 update
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@1461 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/parser')
13 files changed, 2888 insertions, 0 deletions
diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap48bdlAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap48bdlAtom.cpp new file mode 100644 index 000000000..99828d98b --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap48bdlAtom.cpp @@ -0,0 +1,127 @@ +/***************************************************************** +| +| AP4 - 8bdl Atoms +| +| Copyright 2002-2009 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap48bdlAtom.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_8bdlAtom) + +/*---------------------------------------------------------------------- +| AP4_8bdlAtom::AP4_8bdlAtom ++---------------------------------------------------------------------*/ +AP4_8bdlAtom::AP4_8bdlAtom(AP4_UI32 encoding, + AP4_UI32 encoding_version, + const AP4_Byte* data, + AP4_Size data_size) : + AP4_Atom(AP4_ATOM_TYPE_8BDL, (AP4_UI32)(AP4_ATOM_HEADER_SIZE+8+data_size)), + m_Encoding(encoding), + m_EncodingVersion(encoding_version), + m_BundleData(data, data_size) +{ +} + +/*---------------------------------------------------------------------- +| AP4_8bdlAtom::Create ++---------------------------------------------------------------------*/ +AP4_8bdlAtom* +AP4_8bdlAtom::Create(AP4_Size size, AP4_ByteStream& stream) +{ + // make sure we have enough data + if (size < AP4_ATOM_HEADER_SIZE+8) { + return NULL; + } else { + return new AP4_8bdlAtom(size, stream); + } +} + +/*---------------------------------------------------------------------- +| AP4_8bdlAtom::AP4_8bdlAtom ++---------------------------------------------------------------------*/ +AP4_8bdlAtom::AP4_8bdlAtom(AP4_Size size, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_8BDL, (AP4_UI32)(size)), + m_BundleData(size-AP4_ATOM_HEADER_SIZE-8) +{ + stream.ReadUI32(m_Encoding); + stream.ReadUI32(m_EncodingVersion); + m_BundleData.SetDataSize(m_BundleData.GetBufferSize()); + stream.Read(m_BundleData.UseData(), m_BundleData.GetDataSize()); +} + +/*---------------------------------------------------------------------- +| AP4_8bdlAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_8bdlAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // encoding + result = stream.WriteUI32(m_Encoding); + if (AP4_FAILED(result)) return result; + + // encoding version + result = stream.WriteUI32(m_EncodingVersion); + if (AP4_FAILED(result)) return result; + + // bundle_data + result = stream.Write(m_BundleData.GetData(), m_BundleData.GetDataSize()); + if (AP4_FAILED(result)) return result; + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_8bdlAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_8bdlAtom::InspectFields(AP4_AtomInspector& inspector) +{ + char enc[5]; + AP4_FormatFourChars(enc, m_Encoding); + inspector.AddField("encoding", enc); + inspector.AddField("encoding_version", m_EncodingVersion); + if (m_Encoding == AP4_8BDL_XML_DATA_ENCODING) { + // we, in fact have an xml string + AP4_String xml((const char*)m_BundleData.GetData(), m_BundleData.GetDataSize()); + inspector.AddField("bundle_data", xml.GetChars()); + } else { + inspector.AddField("bundle_data", m_BundleData.GetData(), m_BundleData.GetDataSize()); + } + + return AP4_SUCCESS; +} + + + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Protection.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Protection.cpp new file mode 100644 index 000000000..26c873f29 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Protection.cpp @@ -0,0 +1,1184 @@ +/***************************************************************** +| +| AP4 - Protected Stream Support +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| +****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Protection.h" +#include "Ap4SchmAtom.h" +#include "Ap4StsdAtom.h" +#include "Ap4FtypAtom.h" +#include "Ap4Sample.h" +#include "Ap4StreamCipher.h" +#include "Ap4IsfmAtom.h" +#include "Ap4FrmaAtom.h" +#include "Ap4IkmsAtom.h" +#include "Ap4IsfmAtom.h" +#include "Ap4IsltAtom.h" +#include "Ap4Utils.h" +#include "Ap4TrakAtom.h" +#include "Ap4IsmaCryp.h" +#include "Ap4AesBlockCipher.h" +#include "Ap4OmaDcf.h" +#include "Ap4Marlin.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_ProtectedSampleDescription) + +/*---------------------------------------------------------------------- +| AP4_EncaSampleEntry::AP4_EncaSampleEntry ++---------------------------------------------------------------------*/ +AP4_EncaSampleEntry::AP4_EncaSampleEntry(AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_AudioSampleEntry(type, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_EncaSampleEntry::AP4_EncaSampleEntry ++---------------------------------------------------------------------*/ +AP4_EncaSampleEntry::AP4_EncaSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_AudioSampleEntry(AP4_ATOM_TYPE_ENCA, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_EncaSampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_EncaSampleEntry::ToSampleDescription() +{ + // get the original sample format + AP4_FrmaAtom* frma = (AP4_FrmaAtom*)FindChild("sinf/frma"); + + // get the schi atom + AP4_ContainerAtom* schi; + schi = static_cast<AP4_ContainerAtom*>(FindChild("sinf/schi")); + + // get the scheme info + AP4_SchmAtom* schm = (AP4_SchmAtom*)FindChild("sinf/schm"); + AP4_UI32 original_format = frma?frma->GetOriginalFormat():AP4_ATOM_TYPE_MP4A; + if (schm) { + // create the original sample description + return new AP4_ProtectedSampleDescription( + m_Type, + ToTargetSampleDescription(original_format), + original_format, + schm->GetSchemeType(), + schm->GetSchemeVersion(), + schm->GetSchemeUri().GetChars(), + schi); + } else if (schi) { + // try to see if we can guess the protection scheme from the 'schi' contents + AP4_Atom* odkm = schi->GetChild(AP4_ATOM_TYPE_ODKM); + if (odkm) { + // create the original sample description + return new AP4_ProtectedSampleDescription( + m_Type, + ToTargetSampleDescription(original_format), + original_format, + AP4_PROTECTION_SCHEME_TYPE_OMA, + AP4_PROTECTION_SCHEME_VERSION_OMA_20, + NULL, + schi); + } + } + + // unknown scheme + return NULL; +} + +/*---------------------------------------------------------------------- +| AP4_EncvSampleEntry::AP4_EncvSampleEntry ++---------------------------------------------------------------------*/ +AP4_EncvSampleEntry::AP4_EncvSampleEntry(AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_VisualSampleEntry(type, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_EncvSampleEntry::AP4_EncvSampleEntry ++---------------------------------------------------------------------*/ +AP4_EncvSampleEntry::AP4_EncvSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_VisualSampleEntry(AP4_ATOM_TYPE_ENCV, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_EncvSampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_EncvSampleEntry::ToSampleDescription() +{ + // get the original sample format + AP4_FrmaAtom* frma = (AP4_FrmaAtom*)FindChild("sinf/frma"); + + // get the schi atom + AP4_ContainerAtom* schi; + schi = static_cast<AP4_ContainerAtom*>(FindChild("sinf/schi")); + + // get the scheme info + AP4_SchmAtom* schm = (AP4_SchmAtom*)FindChild("sinf/schm"); + AP4_UI32 original_format = frma?frma->GetOriginalFormat():AP4_ATOM_TYPE_MP4V; + if (schm) { + // create the sample description + return new AP4_ProtectedSampleDescription( + m_Type, + ToTargetSampleDescription(original_format), + original_format, + schm->GetSchemeType(), + schm->GetSchemeVersion(), + schm->GetSchemeUri().GetChars(), + schi); + } else if (schi) { + // try to see if we can guess the protection scheme from the 'schi' contents + AP4_Atom* odkm = schi->GetChild(AP4_ATOM_TYPE_ODKM); + if (odkm) { + // create the original sample description + return new AP4_ProtectedSampleDescription( + m_Type, + ToTargetSampleDescription(original_format), + original_format, + AP4_PROTECTION_SCHEME_TYPE_OMA, + AP4_PROTECTION_SCHEME_VERSION_OMA_20, + NULL, + schi); + } + } + + // unknown scheme + return NULL; + +} + +/*---------------------------------------------------------------------- +| AP4_DrmsSampleEntry::AP4_DrmsSampleEntry ++---------------------------------------------------------------------*/ +AP4_DrmsSampleEntry::AP4_DrmsSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_EncaSampleEntry(AP4_ATOM_TYPE_DRMS, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_DrmiSampleEntry::AP4_DrmiSampleEntry ++---------------------------------------------------------------------*/ +AP4_DrmiSampleEntry::AP4_DrmiSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_EncvSampleEntry(AP4_ATOM_TYPE_DRMI, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionSchemeInfo::~AP4_ProtectionSchemeInfo ++---------------------------------------------------------------------*/ +AP4_ProtectionSchemeInfo::~AP4_ProtectionSchemeInfo() +{ + delete m_SchiAtom; +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionSchemeInfo::AP4_ProtectionSchemeInfo ++---------------------------------------------------------------------*/ +AP4_ProtectionSchemeInfo::AP4_ProtectionSchemeInfo(AP4_ContainerAtom* schi) +{ + if (schi) { + m_SchiAtom = (AP4_ContainerAtom*)schi->Clone(); + } else { + m_SchiAtom = NULL; + } +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap::AP4_ProtectionKeyMap ++---------------------------------------------------------------------*/ +AP4_ProtectionKeyMap::AP4_ProtectionKeyMap() +{ +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap::~AP4_ProtectionKeyMap ++---------------------------------------------------------------------*/ +AP4_ProtectionKeyMap::~AP4_ProtectionKeyMap() +{ + m_KeyEntries.DeleteReferences(); +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap::SetKey ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ProtectionKeyMap::SetKey(AP4_UI32 track_id, const AP4_UI08* key, const AP4_UI08* iv) +{ + KeyEntry* entry = GetEntry(track_id); + if (entry == NULL) { + m_KeyEntries.Add(new KeyEntry(track_id, key, iv)); + } else { + entry->SetKey(key, iv); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap::SetKey ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ProtectionKeyMap::SetKeys(const AP4_ProtectionKeyMap& key_map) +{ + AP4_List<KeyEntry>::Item* item = key_map.m_KeyEntries.FirstItem(); + while (item) { + KeyEntry* entry = item->GetData(); + m_KeyEntries.Add(new KeyEntry(entry->m_TrackId, + entry->m_Key, + entry->m_IV)); + item = item->GetNext(); + } + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap::GetKeyIv ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ProtectionKeyMap::GetKeyAndIv(AP4_UI32 track_id, + const AP4_UI08*& key, + const AP4_UI08*& iv) +{ + KeyEntry* entry = GetEntry(track_id); + if (entry) { + key = entry->m_Key; + iv = entry->m_IV; + return AP4_SUCCESS; + } else { + return AP4_ERROR_NO_SUCH_ITEM; + } +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap::GetKey ++---------------------------------------------------------------------*/ +const AP4_UI08* +AP4_ProtectionKeyMap::GetKey(AP4_UI32 track_id) const +{ + KeyEntry* entry = GetEntry(track_id); + if (entry) { + return entry->m_Key; + } else { + return NULL; + } +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap::GetEntry ++---------------------------------------------------------------------*/ +AP4_ProtectionKeyMap::KeyEntry* +AP4_ProtectionKeyMap::GetEntry(AP4_UI32 track_id) const +{ + AP4_List<KeyEntry>::Item* item = m_KeyEntries.FirstItem(); + while (item) { + KeyEntry* entry = (KeyEntry*)item->GetData(); + if (entry->m_TrackId == track_id) return entry; + item = item->GetNext(); + } + + return NULL; +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap::KeyEntry::KeyEntry ++---------------------------------------------------------------------*/ +AP4_ProtectionKeyMap::KeyEntry::KeyEntry(AP4_UI32 track_id, + const AP4_UI08* key, + const AP4_UI08* iv /* = NULL */) : + m_TrackId(track_id) +{ + SetKey(key, iv); +} + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap::KeyEntry::SetKey ++---------------------------------------------------------------------*/ +void +AP4_ProtectionKeyMap::KeyEntry::SetKey(const AP4_UI08* key, const AP4_UI08* iv) +{ + AP4_CopyMemory(m_Key, key, sizeof(m_Key)); + if (iv) { + AP4_CopyMemory(m_IV, iv, sizeof(m_IV)); + } else { + AP4_SetMemory(m_IV, 0, sizeof(m_IV)); + } +} + +/*---------------------------------------------------------------------- +| AP4_TrackPropertyMap::~AP4_TrackPropertyMap ++---------------------------------------------------------------------*/ +AP4_TrackPropertyMap::~AP4_TrackPropertyMap() +{ + m_Entries.DeleteReferences(); +} + +/*---------------------------------------------------------------------- +| AP4_TrackPropertyMap::SetProperty ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrackPropertyMap::SetProperty(AP4_UI32 track_id, + const char* name, + const char* value) +{ + return m_Entries.Add(new Entry(track_id, name, value)); +} + +/*---------------------------------------------------------------------- +| AP4_TrackPropertyMap::SetProperties ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrackPropertyMap::SetProperties(const AP4_TrackPropertyMap& properties) +{ + AP4_List<Entry>::Item* item = properties.m_Entries.FirstItem(); + while (item) { + Entry* entry = item->GetData(); + m_Entries.Add(new Entry(entry->m_TrackId, + entry->m_Name.GetChars(), + entry->m_Value.GetChars())); + item = item->GetNext(); + } + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_TrackPropertyMap::GetProperty ++---------------------------------------------------------------------*/ +const char* +AP4_TrackPropertyMap::GetProperty(AP4_UI32 track_id, const char* name) +{ + AP4_List<Entry>::Item* item = m_Entries.FirstItem(); + while (item) { + Entry* entry = item->GetData(); + if (entry->m_TrackId == track_id && + AP4_CompareStrings(entry->m_Name.GetChars(), name) == 0) { + return entry->m_Value.GetChars(); + } + item = item->GetNext(); + } + + // not found + return NULL; +} + +/*---------------------------------------------------------------------- +| AP4_TrackPropertyMap::GetTextualHeaders ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrackPropertyMap::GetTextualHeaders(AP4_UI32 track_id, AP4_DataBuffer& textual_headers) +{ + AP4_Size buffer_size = 0; + AP4_Result result = AP4_SUCCESS; + AP4_Byte* data_buffer; + + // get the size needed for the textual headers + AP4_List<Entry>::Item* item = m_Entries.FirstItem(); + while (item) { + Entry* entry = item->GetData(); + if (entry->m_TrackId == track_id) { + const char* name = entry->m_Name.GetChars(); + if (AP4_CompareStrings(name, "ContentId") != 0 && + AP4_CompareStrings(name, "RightsIssuerUrl") != 0) { + buffer_size += (entry->m_Name.GetLength() + + entry->m_Value.GetLength() + + 2); // colon + nul + + } + } + item = item->GetNext(); + } + + result = textual_headers.SetDataSize(buffer_size); + AP4_CHECK(result); + + data_buffer = textual_headers.UseData(); + + // set the textual headers + item = m_Entries.FirstItem(); + while (item) { + Entry* entry = item->GetData(); + if (entry->m_TrackId == track_id) { + const char* name = entry->m_Name.GetChars(); + const char* value = NULL; + AP4_Size name_len = 0; + AP4_Size value_len = 0; + + if (AP4_CompareStrings(name, "ContentId") != 0 && + AP4_CompareStrings(name, "RightsIssuerUrl") != 0) { + name_len = entry->m_Name.GetLength(); + value = entry->m_Value.GetChars(); + value_len = entry->m_Value.GetLength(); + + // format is name:value\0 + if (name && value) { + AP4_CopyMemory(data_buffer, name, name_len); + data_buffer[name_len] = ':'; + data_buffer += (1+name_len); + AP4_CopyMemory(data_buffer, value, value_len); + data_buffer[value_len] = '\0'; + data_buffer += (1+value_len); + } + } + } + item = item->GetNext(); + } + + // success path + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ProtectedSampleDescription::AP4_ProtectedSampleDescription ++---------------------------------------------------------------------*/ +AP4_ProtectedSampleDescription::AP4_ProtectedSampleDescription( + AP4_UI32 format, + AP4_SampleDescription* original_sample_description, + AP4_UI32 original_format, + AP4_UI32 scheme_type, + AP4_UI32 scheme_version, + const char* scheme_uri, + AP4_ContainerAtom* schi, + bool transfer_ownership_of_original /* = true */) : + AP4_SampleDescription(TYPE_PROTECTED, format, NULL), + m_OriginalSampleDescription(original_sample_description), + m_OriginalSampleDescriptionIsOwned(transfer_ownership_of_original), + m_OriginalFormat(original_format), + m_SchemeType(scheme_type), + m_SchemeVersion(scheme_version), + m_SchemeUri(scheme_uri) +{ + m_SchemeInfo = new AP4_ProtectionSchemeInfo(schi); +} + +/*---------------------------------------------------------------------- +| AP4_ProtectedSampleDescription::~AP4_ProtectedSampleDescription ++---------------------------------------------------------------------*/ +AP4_ProtectedSampleDescription::~AP4_ProtectedSampleDescription() +{ + delete m_SchemeInfo; + if (m_OriginalSampleDescriptionIsOwned) delete m_OriginalSampleDescription; +} + +/*---------------------------------------------------------------------- +| AP4_ProtectedSampleDescription::ToAtom ++---------------------------------------------------------------------*/ +AP4_Atom* +AP4_ProtectedSampleDescription::ToAtom() const +{ + // construct the atom for the original sample description + if (m_OriginalSampleDescription == NULL) return NULL; + AP4_Atom* atom = m_OriginalSampleDescription->ToAtom(); + + // switch the atom type + atom->SetType(m_Format); + + // check that the constructed atom is a container + AP4_ContainerAtom* container = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom); + if (container == NULL) return atom; // not a container ?? return now. + + // create the sinf atom + AP4_ContainerAtom* sinf = new AP4_ContainerAtom(AP4_ATOM_TYPE_SINF); + + // create and add a frma atom + AP4_FrmaAtom* frma = new AP4_FrmaAtom(m_OriginalFormat); + sinf->AddChild(frma); + + // create and add a schm atom + AP4_SchmAtom* schm = new AP4_SchmAtom(m_SchemeType, m_SchemeVersion, m_SchemeUri.GetChars()); + sinf->AddChild(schm); + + // add the schi atom + if (m_SchemeInfo && m_SchemeInfo->GetSchiAtom()) { + sinf->AddChild(m_SchemeInfo->GetSchiAtom()->Clone()); + } + + // add the sinf to the returned atom + container->AddChild(sinf); + + return atom; +} + +/*---------------------------------------------------------------------- +| AP4_SampleDecrypter:Create ++---------------------------------------------------------------------*/ +AP4_SampleDecrypter* +AP4_SampleDecrypter::Create(AP4_ProtectedSampleDescription* sample_description, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory) +{ + if (sample_description == NULL || key == NULL) return NULL; + + // select the block cipher factory + if (block_cipher_factory == NULL) { + block_cipher_factory = &AP4_DefaultBlockCipherFactory::Instance; + } + + switch(sample_description->GetSchemeType()) { + case AP4_PROTECTION_SCHEME_TYPE_OMA: { + AP4_OmaDcfSampleDecrypter* decrypter = NULL; + AP4_Result result = AP4_OmaDcfSampleDecrypter::Create(sample_description, + key, + key_size, + block_cipher_factory, + decrypter); + if (AP4_FAILED(result)) return NULL; + return decrypter; + } + + case AP4_PROTECTION_SCHEME_TYPE_IAEC: { + AP4_IsmaCipher* decrypter = NULL; + AP4_Result result = AP4_IsmaCipher::CreateSampleDecrypter(sample_description, + key, + key_size, + block_cipher_factory, + decrypter); + if (AP4_FAILED(result)) return NULL; + return decrypter; + } + + default: + return NULL; + } + + return NULL; +} + +/*---------------------------------------------------------------------- +| AP4_StandardDecryptingProcessor:AP4_StandardDecryptingProcessor ++---------------------------------------------------------------------*/ +AP4_StandardDecryptingProcessor::AP4_StandardDecryptingProcessor( + const AP4_ProtectionKeyMap* key_map /* = NULL */, + AP4_BlockCipherFactory* block_cipher_factory /* = NULL */) +{ + if (key_map) { + // copy the keys + m_KeyMap.SetKeys(*key_map); + } + + if (block_cipher_factory == NULL) { + m_BlockCipherFactory = &AP4_DefaultBlockCipherFactory::Instance; + } else { + m_BlockCipherFactory = block_cipher_factory; + } +} + +/*---------------------------------------------------------------------- +| AP4_StandardDecryptingProcessor:CreateTrackHandler ++---------------------------------------------------------------------*/ +AP4_Processor::TrackHandler* +AP4_StandardDecryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) +{ + // find the stsd atom + AP4_StsdAtom* stsd = AP4_DYNAMIC_CAST(AP4_StsdAtom, trak->FindChild("mdia/minf/stbl/stsd")); + + // avoid tracks with no stsd atom (should not happen) + if (stsd == NULL) return NULL; + + // we only look at the first sample description + AP4_SampleDescription* desc = stsd->GetSampleDescription(0); + AP4_SampleEntry* entry = stsd->GetSampleEntry(0); + if (desc == NULL || entry == NULL) return NULL; + if (desc->GetType() == AP4_SampleDescription::TYPE_PROTECTED) { + // create a handler for this track + AP4_ProtectedSampleDescription* protected_desc = + static_cast<AP4_ProtectedSampleDescription*>(desc); + if (protected_desc->GetSchemeType() == AP4_PROTECTION_SCHEME_TYPE_OMA) { + const AP4_UI08* key = m_KeyMap.GetKey(trak->GetId()); + if (key) { + AP4_OmaDcfTrackDecrypter* handler = NULL; + AP4_Result result = AP4_OmaDcfTrackDecrypter::Create(key, + AP4_CIPHER_BLOCK_SIZE, + protected_desc, + entry, + m_BlockCipherFactory, + handler); + if (AP4_FAILED(result)) return NULL; + return handler; + } + } else if (protected_desc->GetSchemeType() == AP4_PROTECTION_SCHEME_TYPE_IAEC) { + const AP4_UI08* key = m_KeyMap.GetKey(trak->GetId()); + if (key) { + AP4_IsmaTrackDecrypter* handler = NULL; + AP4_Result result = AP4_IsmaTrackDecrypter::Create(key, + AP4_CIPHER_BLOCK_SIZE, + protected_desc, + entry, + m_BlockCipherFactory, + handler); + if (AP4_FAILED(result)) return NULL; + return handler; + } + } + } + + return NULL; +} + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream::AP4_DecryptingStream ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DecryptingStream::Create(CipherMode mode, + AP4_ByteStream& encrypted_stream, + AP4_LargeSize cleartext_size, + const AP4_UI08* iv, + AP4_Size iv_size, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ByteStream*& stream) +{ + // default return value + stream = NULL; + + // default cipher settings + if (block_cipher_factory == NULL) { + block_cipher_factory = &AP4_DefaultBlockCipherFactory::Instance; + } + + // get the encrypted size (includes padding) + AP4_LargeSize encrypted_size = 0; + AP4_Result result = encrypted_stream.GetSize(encrypted_size); + if (AP4_FAILED(result)) return result; + + // check IV + if (iv == NULL || iv_size != 16) return AP4_ERROR_INVALID_PARAMETERS; + + // check that the encrypted size is consistent with the cipher mode + if (mode == CIPHER_MODE_CBC) { + // we need at least 32 bytes of data+padding + // we also need a multiple of the block size + if (encrypted_size < 32 || ((encrypted_size % 16) != 0)) { + return AP4_ERROR_INVALID_FORMAT; + } + } + + // create the stream cipher + AP4_BlockCipher* block_cipher; + result = block_cipher_factory->Create(AP4_BlockCipher::AES_128, + (mode == CIPHER_MODE_CTR ? + AP4_BlockCipher::ENCRYPT : + AP4_BlockCipher::DECRYPT), + key, key_size, block_cipher); + if (AP4_FAILED(result)) return result; + + // keep a reference to the source stream + encrypted_stream.AddReference(); + + // create the stream + AP4_DecryptingStream* dec_stream = new AP4_DecryptingStream(); + stream = dec_stream; + dec_stream->m_Mode = mode; + dec_stream->m_CleartextSize = cleartext_size; + dec_stream->m_CleartextPosition = 0; + dec_stream->m_EncryptedSize = encrypted_size; + dec_stream->m_EncryptedStream = &encrypted_stream; + dec_stream->m_EncryptedPosition = 0; + dec_stream->m_BufferFullness = 0; + dec_stream->m_BufferOffset = 0; + dec_stream->m_ReferenceCount = 1; + + // create the cipher according to the mode + switch (mode) { + case CIPHER_MODE_CBC: + dec_stream->m_StreamCipher = new AP4_CbcStreamCipher(block_cipher, + AP4_StreamCipher::DECRYPT); + break; + case CIPHER_MODE_CTR: + dec_stream->m_StreamCipher = new AP4_CtrStreamCipher(block_cipher, + NULL, + AP4_CIPHER_BLOCK_SIZE); + break; + default: + // should never occur + AP4_ASSERT(0); + } + + // set the IV + dec_stream->m_StreamCipher->SetIV(iv); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream::~AP4_DecryptingStream ++---------------------------------------------------------------------*/ +AP4_DecryptingStream::~AP4_DecryptingStream() +{ + delete m_StreamCipher; + m_EncryptedStream->Release(); +} + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream::AddReference ++---------------------------------------------------------------------*/ +void +AP4_DecryptingStream::AddReference() +{ + ++m_ReferenceCount; +} + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream::Release ++---------------------------------------------------------------------*/ +void +AP4_DecryptingStream::Release() +{ + if (--m_ReferenceCount == 0) delete this; +} + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream::ReadPartial ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DecryptingStream::ReadPartial(void* buffer, + AP4_Size bytes_to_read, + AP4_Size& bytes_read) +{ + bytes_read = 0; + + // never read more than what's available + AP4_LargeSize available = m_CleartextSize-m_CleartextPosition; + if (available < bytes_to_read) { + if (available == 0) { + return AP4_ERROR_EOS; + } + bytes_to_read = (AP4_Size)available; + } + + if (m_BufferFullness) { + // we have some leftovers + AP4_Size chunk = bytes_to_read; + if (chunk > m_BufferFullness) chunk = m_BufferFullness; + AP4_CopyMemory(buffer, &m_Buffer[m_BufferOffset], chunk); + buffer = (char*)buffer+chunk; + m_CleartextPosition += chunk; + available -= chunk; + bytes_to_read -= chunk; + m_BufferFullness -= chunk; + m_BufferOffset += chunk; + bytes_read += chunk; + } + + // seek to the right place in the input + m_EncryptedStream->Seek(m_EncryptedPosition); + + while (bytes_to_read) { + // read from the source + AP4_UI08 encrypted[16]; + AP4_Size encrypted_read = 0; + AP4_Result result = m_EncryptedStream->ReadPartial(encrypted, 16, encrypted_read); + if (result == AP4_ERROR_EOS) { + if (bytes_read == 0) { + return AP4_ERROR_EOS; + } else { + return AP4_SUCCESS; + } + } else if (result != AP4_SUCCESS) { + return result; + } else { + m_EncryptedPosition += encrypted_read; + } + bool is_last_buffer = (m_EncryptedPosition >= m_EncryptedSize); + AP4_Size buffer_size = 16; + result = m_StreamCipher->ProcessBuffer(encrypted, + encrypted_read, + m_Buffer, + &buffer_size, + is_last_buffer); + m_BufferOffset = 0; + m_BufferFullness = buffer_size; + + AP4_Size chunk = bytes_to_read; + if (chunk > m_BufferFullness) chunk = m_BufferFullness; + AP4_CopyMemory(buffer, &m_Buffer[m_BufferOffset], chunk); + buffer = (char*)buffer+chunk; + m_CleartextPosition += chunk; + available -= chunk; + bytes_to_read -= chunk; + m_BufferFullness -= chunk; + m_BufferOffset += chunk; + bytes_read += chunk; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream::WritePartial ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DecryptingStream::WritePartial(const void* /* buffer */, + AP4_Size /* bytes_to_write */, + AP4_Size& /* bytes_written */) +{ + return AP4_ERROR_NOT_SUPPORTED; +} + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream::Seek ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DecryptingStream::Seek(AP4_Position position) +{ + AP4_Cardinal preroll = 0; + + // check bounds + if (position > m_CleartextSize) { + return AP4_ERROR_INVALID_PARAMETERS; + } + + // try to put the stream cipher at the right offset + AP4_CHECK(m_StreamCipher->SetStreamOffset(position, &preroll)); + + // seek in the source stream + AP4_CHECK(m_EncryptedStream->Seek(position-preroll)); + + // if we need to, process the preroll bytes + if (preroll > 0) { + AP4_Size out_size = 0; + AP4_UI08 buffer[2*AP4_CIPHER_BLOCK_SIZE]; // bigger than preroll + AP4_CHECK(m_EncryptedStream->Read(buffer, preroll)); + AP4_CHECK(m_StreamCipher->ProcessBuffer(buffer, preroll, buffer, &out_size)); + AP4_ASSERT(out_size == 0); // we're just feeding prerolled bytes, + // there can be no output + } + + // update the counters + m_CleartextPosition = position; + m_EncryptedPosition = position; + m_BufferFullness = 0; + m_BufferOffset = 0; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream::Tell ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DecryptingStream::Tell(AP4_Position& position) +{ + position = m_CleartextPosition; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream::GetSize ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DecryptingStream::GetSize(AP4_LargeSize& size) +{ + size = m_CleartextSize; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream::AP4_EncryptingStream ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EncryptingStream::Create(CipherMode mode, + AP4_ByteStream& cleartext_stream, + const AP4_UI08* iv, + AP4_Size iv_size, + const AP4_UI08* key, + AP4_Size key_size, + bool prepend_iv, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ByteStream*& stream) +{ + // default return value + stream = NULL; + + // get the cleartext size + AP4_LargeSize cleartext_size = 0; + AP4_Result result = cleartext_stream.GetSize(cleartext_size); + if (AP4_FAILED(result)) return result; + + // check IV + if (iv == NULL || iv_size != 16) return AP4_ERROR_INVALID_PARAMETERS; + + // compute the encrypted size + AP4_LargeSize encrypted_size = cleartext_size; + if (mode == CIPHER_MODE_CBC) { + encrypted_size += (16-(cleartext_size%16)); // with padding + } + + // create the stream cipher + AP4_BlockCipher* block_cipher; + result = block_cipher_factory->Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::ENCRYPT, + key, key_size, block_cipher); + if (AP4_FAILED(result)) return result; + + // keep a reference to the source stream + cleartext_stream.AddReference(); + + // create the stream + AP4_EncryptingStream* enc_stream = new AP4_EncryptingStream(); + stream = enc_stream; + enc_stream->m_Mode = mode; + enc_stream->m_CleartextStream = &cleartext_stream; + enc_stream->m_CleartextSize = cleartext_size; + enc_stream->m_CleartextPosition = 0; + enc_stream->m_EncryptedSize = encrypted_size; + enc_stream->m_EncryptedPosition = 0; + enc_stream->m_BufferFullness = 0; + enc_stream->m_BufferOffset = 0; + enc_stream->m_ReferenceCount = 1; + + // deal with the prepended IV if required + if (prepend_iv) { + enc_stream->m_EncryptedSize += 16; + enc_stream->m_BufferFullness = 16; + AP4_CopyMemory(enc_stream->m_Buffer, iv, 16); + } + + // create the cipher according to the mode + switch (mode) { + case CIPHER_MODE_CBC: + enc_stream->m_StreamCipher = new AP4_CbcStreamCipher(block_cipher, + AP4_StreamCipher::ENCRYPT); + break; + case CIPHER_MODE_CTR: + enc_stream->m_StreamCipher = new AP4_CtrStreamCipher(block_cipher, + NULL, + AP4_CIPHER_BLOCK_SIZE); + break; + default: + // should never occur + AP4_ASSERT(0); + } + + // set the IV + enc_stream->m_StreamCipher->SetIV(iv); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream::~AP4_EncryptingStream ++---------------------------------------------------------------------*/ +AP4_EncryptingStream::~AP4_EncryptingStream() +{ + delete m_StreamCipher; + m_CleartextStream->Release(); +} + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream::AddReference ++---------------------------------------------------------------------*/ +void +AP4_EncryptingStream::AddReference() +{ + ++m_ReferenceCount; +} + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream::Release ++---------------------------------------------------------------------*/ +void +AP4_EncryptingStream::Release() +{ + if (--m_ReferenceCount == 0) delete this; +} + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream::ReadPartial ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EncryptingStream::ReadPartial(void* buffer, + AP4_Size bytes_to_read, + AP4_Size& bytes_read) +{ + bytes_read = 0; + + // never read more than what's available + AP4_LargeSize available = m_EncryptedSize-m_EncryptedPosition; + if (available < bytes_to_read) { + if (available == 0) return AP4_ERROR_EOS; + bytes_to_read = (AP4_Size)available; + } + + if (m_BufferFullness) { + // we have some leftovers + AP4_Size chunk = bytes_to_read; + if (chunk > m_BufferFullness) chunk = m_BufferFullness; + AP4_CopyMemory(buffer, &m_Buffer[m_BufferOffset], chunk); + buffer = (char*)buffer+chunk; + m_EncryptedPosition += chunk; + available -= chunk; + bytes_to_read -= chunk; + m_BufferFullness -= chunk; + m_BufferOffset += chunk; + bytes_read += chunk; + } + + // seek to the right place in the input + m_CleartextStream->Seek(m_CleartextPosition); + + while (bytes_to_read) { + // read from the source + AP4_UI08 cleartext[16]; + AP4_Size cleartext_read = 0; + AP4_Result result = m_CleartextStream->ReadPartial(cleartext, 16, cleartext_read); + if (result == AP4_ERROR_EOS) { + if (bytes_read == 0) { + return AP4_ERROR_EOS; + } else { + return AP4_SUCCESS; + } + } else if (result != AP4_SUCCESS) { + return result; + } else { + m_CleartextPosition += cleartext_read; + } + bool is_last_buffer = (m_CleartextPosition >= m_CleartextSize); + AP4_Size buffer_size = 32; // enough for one block plus one block padding + result = m_StreamCipher->ProcessBuffer(cleartext, + cleartext_read, + m_Buffer, + &buffer_size, + is_last_buffer); + m_BufferOffset = 0; + m_BufferFullness = buffer_size; + + AP4_Size chunk = bytes_to_read; + if (chunk > m_BufferFullness) chunk = m_BufferFullness; + if (chunk) { + AP4_CopyMemory(buffer, &m_Buffer[m_BufferOffset], chunk); + buffer = (char*)buffer+chunk; + m_EncryptedPosition += chunk; + available -= chunk; + bytes_to_read -= chunk; + m_BufferFullness -= chunk; + m_BufferOffset += chunk; + bytes_read += chunk; + } + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream::WritePartial ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EncryptingStream::WritePartial(const void* /* buffer */, + AP4_Size /* bytes_to_write */, + AP4_Size& /* bytes_written */) +{ + return AP4_ERROR_NOT_SUPPORTED; +} + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream::Seek ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EncryptingStream::Seek(AP4_Position position) +{ + if (position == m_EncryptedPosition) { + return AP4_SUCCESS; + } else { + return AP4_ERROR_NOT_SUPPORTED; + } +} + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream::Tell ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EncryptingStream::Tell(AP4_Position& position) +{ + position = m_EncryptedPosition; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream::GetSize ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EncryptingStream::GetSize(AP4_LargeSize& size) +{ + size = m_EncryptedSize; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DefaultBlockCipherFactory::Instance ++---------------------------------------------------------------------*/ +AP4_DefaultBlockCipherFactory AP4_DefaultBlockCipherFactory::Instance; + +/*---------------------------------------------------------------------- +| AP4_DefaultBlockCipherFactory ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DefaultBlockCipherFactory::Create(AP4_BlockCipher::CipherType type, + AP4_BlockCipher::CipherDirection direction, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipher*& cipher) +{ + // setup default return vaule + cipher = NULL; + + switch (type) { + case AP4_BlockCipher::AES_128: + // check cipher parameters + if (key == NULL || key_size != AP4_AES_BLOCK_SIZE) { + return AP4_ERROR_INVALID_PARAMETERS; + } + + // create the cipher + cipher = new AP4_AesBlockCipher(key, direction); + return AP4_SUCCESS; + + default: + // not supported + return AP4_ERROR_NOT_SUPPORTED; + } +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Protection.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Protection.h new file mode 100644 index 000000000..0e4a4bd76 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Protection.h @@ -0,0 +1,451 @@ +/***************************************************************** +| +| AP4 - Protected Streams support +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| +****************************************************************/ + +#ifndef _AP4_PROTECTION_H_ +#define _AP4_PROTECTION_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4SampleEntry.h" +#include "Ap4Atom.h" +#include "Ap4AtomFactory.h" +#include "Ap4SampleDescription.h" +#include "Ap4Processor.h" + +/*---------------------------------------------------------------------- +| classes ++---------------------------------------------------------------------*/ +class AP4_StreamCipher; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +// this is fixed for now +const unsigned int AP4_PROTECTION_KEY_LENGTH = 16; + +const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_ITUNES = AP4_ATOM_TYPE('i','t','u','n'); + +/*---------------------------------------------------------------------- +| AP4_EncaSampleEntry ++---------------------------------------------------------------------*/ +class AP4_EncaSampleEntry : public AP4_AudioSampleEntry +{ +public: + // methods + AP4_EncaSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + AP4_EncaSampleEntry(AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // methods + AP4_SampleDescription* ToSampleDescription(); +}; + +/*---------------------------------------------------------------------- +| AP4_EncvSampleEntry ++---------------------------------------------------------------------*/ +class AP4_EncvSampleEntry : public AP4_VisualSampleEntry +{ +public: + // constructors + AP4_EncvSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + AP4_EncvSampleEntry(AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // methods + AP4_SampleDescription* ToSampleDescription(); +}; + +/*---------------------------------------------------------------------- +| AP4_DrmsSampleEntry ++---------------------------------------------------------------------*/ +class AP4_DrmsSampleEntry : public AP4_EncaSampleEntry +{ +public: + // methods + AP4_DrmsSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); +}; + +/*---------------------------------------------------------------------- +| AP4_DrmiSampleEntry ++---------------------------------------------------------------------*/ +class AP4_DrmiSampleEntry : public AP4_EncvSampleEntry +{ +public: + // methods + AP4_DrmiSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); +}; + +/*---------------------------------------------------------------------- +| AP4_ProtectionKeyMap ++---------------------------------------------------------------------*/ +class AP4_ProtectionKeyMap +{ +public: + // constructors and destructor + AP4_ProtectionKeyMap(); + ~AP4_ProtectionKeyMap(); + + // methods + AP4_Result SetKey(AP4_UI32 track_id, const AP4_UI08* key, const AP4_UI08* iv = NULL); + AP4_Result SetKeys(const AP4_ProtectionKeyMap& key_map); + AP4_Result GetKeyAndIv(AP4_UI32 track_id, const AP4_UI08*& key, const AP4_UI08*& iv); + const AP4_UI08* GetKey(AP4_UI32 track_id) const; + +private: + // types + class KeyEntry { + public: + KeyEntry(AP4_UI32 track_id, const AP4_UI08* key, const AP4_UI08* iv = NULL); + void SetKey(const AP4_UI08* key, const AP4_UI08* iv); + AP4_Ordinal m_TrackId; + AP4_UI08 m_Key[AP4_PROTECTION_KEY_LENGTH]; + AP4_UI08 m_IV[AP4_PROTECTION_KEY_LENGTH]; + }; + + // methods + KeyEntry* GetEntry(AP4_UI32 track_id) const; + + // members + AP4_List<KeyEntry> m_KeyEntries; +}; + +/*---------------------------------------------------------------------- +| AP4_TrackPropertyMap ++---------------------------------------------------------------------*/ +class AP4_TrackPropertyMap +{ +public: + // methods + AP4_Result SetProperty(AP4_UI32 track_id, const char* name, const char* value); + AP4_Result SetProperties(const AP4_TrackPropertyMap& properties); + const char* GetProperty(AP4_UI32 track_id, const char* name); + AP4_Result GetTextualHeaders(AP4_UI32 track_id, AP4_DataBuffer& buffer); + + + // destructor + virtual ~AP4_TrackPropertyMap(); + +private: + // types + class Entry { + public: + Entry(AP4_UI32 track_id, const char* name, const char* value) : + m_TrackId(track_id), m_Name(name), m_Value(value) {} + AP4_UI32 m_TrackId; + AP4_String m_Name; + AP4_String m_Value; + }; + + // members + AP4_List<Entry> m_Entries; +}; + +/*---------------------------------------------------------------------- +| AP4_ProtectionSchemeInfo ++---------------------------------------------------------------------*/ +class AP4_ProtectionSchemeInfo +{ +public: + // constructors and destructor + AP4_ProtectionSchemeInfo(AP4_ContainerAtom* schi); + virtual ~AP4_ProtectionSchemeInfo(); + + // accessors + AP4_ContainerAtom* GetSchiAtom() { return m_SchiAtom; } + +protected: + AP4_ContainerAtom* m_SchiAtom; +}; + +/*---------------------------------------------------------------------- +| AP4_ProtectedSampleDescription ++---------------------------------------------------------------------*/ +class AP4_ProtectedSampleDescription : public AP4_SampleDescription +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_ProtectedSampleDescription, AP4_SampleDescription) + + // constructor and destructor + AP4_ProtectedSampleDescription(AP4_UI32 format, + AP4_SampleDescription* original_sample_description, + AP4_UI32 original_format, + AP4_UI32 scheme_type, + AP4_UI32 scheme_version, + const char* scheme_uri, + AP4_ContainerAtom* schi_atom, // will be cloned + bool transfer_ownership_of_original=true); + ~AP4_ProtectedSampleDescription(); + + // accessors + AP4_SampleDescription* GetOriginalSampleDescription() { + return m_OriginalSampleDescription; + } + AP4_UI32 GetOriginalFormat() const { return m_OriginalFormat; } + AP4_UI32 GetSchemeType() const { return m_SchemeType; } + AP4_UI32 GetSchemeVersion() const { return m_SchemeVersion; } + const AP4_String& GetSchemeUri() const { return m_SchemeUri; } + AP4_ProtectionSchemeInfo* GetSchemeInfo() const { + return m_SchemeInfo; + } + + // implementation of abstract base class methods + virtual AP4_Atom* ToAtom() const; + +private: + // members + AP4_SampleDescription* m_OriginalSampleDescription; + bool m_OriginalSampleDescriptionIsOwned; + AP4_UI32 m_OriginalFormat; + AP4_UI32 m_SchemeType; + AP4_UI32 m_SchemeVersion; + AP4_String m_SchemeUri; + AP4_ProtectionSchemeInfo* m_SchemeInfo; +}; + +/*---------------------------------------------------------------------- +| AP4_BlockCipher ++---------------------------------------------------------------------*/ +class AP4_BlockCipher +{ +public: + // types + typedef enum { + ENCRYPT, + DECRYPT + } CipherDirection; + + typedef enum { + AES_128 + } CipherType; + + // constructor and destructor + virtual ~AP4_BlockCipher() {} + + // methods + virtual AP4_Result ProcessBlock(const AP4_UI08* block_in, AP4_UI08* block_out) = 0; +}; + +/*---------------------------------------------------------------------- +| AP4_BlockCipherFactory ++---------------------------------------------------------------------*/ +class AP4_BlockCipherFactory +{ +public: + // methods + virtual ~AP4_BlockCipherFactory() {} + virtual AP4_Result Create(AP4_BlockCipher::CipherType type, + AP4_BlockCipher::CipherDirection direction, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipher*& cipher) = 0; +}; + +/*---------------------------------------------------------------------- +| AP4_DefaultBlockCipherFactory ++---------------------------------------------------------------------*/ +class AP4_DefaultBlockCipherFactory : public AP4_BlockCipherFactory +{ +public: + // class variables + static AP4_DefaultBlockCipherFactory Instance; + + // methods + virtual AP4_Result Create(AP4_BlockCipher::CipherType type, + AP4_BlockCipher::CipherDirection direction, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipher*& cipher); +}; + +/*---------------------------------------------------------------------- +| AP4_SampleDecrypter ++---------------------------------------------------------------------*/ +class AP4_SampleDecrypter +{ +public: + // factory + static AP4_SampleDecrypter* Create(AP4_ProtectedSampleDescription* sample_description, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory = NULL); + + // destructor + virtual ~AP4_SampleDecrypter() {} + + // methods + virtual AP4_Size GetDecryptedSampleSize(AP4_Sample& sample) = 0; + virtual AP4_Result DecryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out) = 0; +}; + +/*---------------------------------------------------------------------- +| AP4_StandardDecryptingProcessor ++---------------------------------------------------------------------*/ +class AP4_StandardDecryptingProcessor : public AP4_Processor +{ +public: + // constructor + AP4_StandardDecryptingProcessor(const AP4_ProtectionKeyMap* key_map = NULL, + AP4_BlockCipherFactory* block_cipher_factory = NULL); + + // accessors + AP4_ProtectionKeyMap& GetKeyMap() { return m_KeyMap; } + + // methods + virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak); + +private: + // members + AP4_BlockCipherFactory* m_BlockCipherFactory; + AP4_ProtectionKeyMap m_KeyMap; +}; + +/*---------------------------------------------------------------------- +| AP4_DecryptingStream ++---------------------------------------------------------------------*/ +class AP4_DecryptingStream : public AP4_ByteStream { +public: + typedef enum { + CIPHER_MODE_CTR, + CIPHER_MODE_CBC + } CipherMode; + + static AP4_Result Create(CipherMode mode, + AP4_ByteStream& encrypted_stream, + AP4_LargeSize cleartext_size, + const AP4_UI08* iv, + AP4_Size iv_size, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ByteStream*& stream); + + // AP4_ByteStream methods + virtual AP4_Result ReadPartial(void* buffer, + AP4_Size bytes_to_read, + AP4_Size& bytes_read); + virtual AP4_Result WritePartial(const void* buffer, + AP4_Size bytes_to_write, + AP4_Size& bytes_written); + virtual AP4_Result Seek(AP4_Position position); + virtual AP4_Result Tell(AP4_Position& position); + virtual AP4_Result GetSize(AP4_LargeSize& size); + + // AP4_Referenceable methods + virtual void AddReference(); + virtual void Release(); + +private: + // methods + AP4_DecryptingStream() {} // private constructor, use the factory instead + ~AP4_DecryptingStream(); + + // members + CipherMode m_Mode; + AP4_LargeSize m_CleartextSize; + AP4_Position m_CleartextPosition; + AP4_ByteStream* m_EncryptedStream; + AP4_LargeSize m_EncryptedSize; + AP4_Position m_EncryptedPosition; + AP4_StreamCipher* m_StreamCipher; + AP4_UI08 m_Buffer[16]; + AP4_Size m_BufferFullness; + AP4_Size m_BufferOffset; + AP4_Cardinal m_ReferenceCount; +}; + +/*---------------------------------------------------------------------- +| AP4_EncryptingStream ++---------------------------------------------------------------------*/ +class AP4_EncryptingStream : public AP4_ByteStream { +public: + typedef enum { + CIPHER_MODE_CTR, + CIPHER_MODE_CBC + } CipherMode; + + static AP4_Result Create(CipherMode mode, + AP4_ByteStream& cleartext_stream, + const AP4_UI08* iv, + AP4_Size iv_size, + const AP4_UI08* key, + AP4_Size key_size, + bool prepend_iv, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ByteStream*& stream); + + // AP4_ByteStream methods + virtual AP4_Result ReadPartial(void* buffer, + AP4_Size bytes_to_read, + AP4_Size& bytes_read); + virtual AP4_Result WritePartial(const void* buffer, + AP4_Size bytes_to_write, + AP4_Size& bytes_written); + virtual AP4_Result Seek(AP4_Position position); + virtual AP4_Result Tell(AP4_Position& position); + virtual AP4_Result GetSize(AP4_LargeSize& size); + + // AP4_Referenceable methods + virtual void AddReference(); + virtual void Release(); + +private: + // methods + AP4_EncryptingStream() {} // private constructor, use the factory instead + ~AP4_EncryptingStream(); + + // members + CipherMode m_Mode; + AP4_LargeSize m_CleartextSize; + AP4_Position m_CleartextPosition; + AP4_ByteStream* m_CleartextStream; + AP4_LargeSize m_EncryptedSize; + AP4_Position m_EncryptedPosition; + AP4_StreamCipher* m_StreamCipher; + AP4_UI08 m_Buffer[32]; // one cipher block plus one block padding + AP4_Size m_BufferFullness; + AP4_Size m_BufferOffset; + AP4_Cardinal m_ReferenceCount; +}; + + +#endif // _AP4_PROTECTION_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Results.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Results.cpp new file mode 100644 index 000000000..1bb2c5cd8 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Results.cpp @@ -0,0 +1,68 @@ +/***************************************************************** +| +| Bento4 - Result Code Map +| +| This file is automatically generated by a script, do not edit! +| +| Copyright (c) 2002-2009, Axiomatic Systems, LLC. +| All rights reserved. +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Results.h" + +/*---------------------------------------------------------------------- +| AP4_ResultText ++---------------------------------------------------------------------*/ +const char* +AP4_ResultText(int result) +{ + switch (result) { + case AP4_SUCCESS: return "AP4_SUCCESS"; + case AP4_FAILURE: return "AP4_FAILURE"; + case AP4_ERROR_OUT_OF_MEMORY: return "AP4_ERROR_OUT_OF_MEMORY"; + case AP4_ERROR_INVALID_PARAMETERS: return "AP4_ERROR_INVALID_PARAMETERS"; + case AP4_ERROR_NO_SUCH_FILE: return "AP4_ERROR_NO_SUCH_FILE"; + case AP4_ERROR_PERMISSION_DENIED: return "AP4_ERROR_PERMISSION_DENIED"; + case AP4_ERROR_CANNOT_OPEN_FILE: return "AP4_ERROR_CANNOT_OPEN_FILE"; + case AP4_ERROR_EOS: return "AP4_ERROR_EOS"; + case AP4_ERROR_WRITE_FAILED: return "AP4_ERROR_WRITE_FAILED"; + case AP4_ERROR_READ_FAILED: return "AP4_ERROR_READ_FAILED"; + case AP4_ERROR_INVALID_FORMAT: return "AP4_ERROR_INVALID_FORMAT"; + case AP4_ERROR_NO_SUCH_ITEM: return "AP4_ERROR_NO_SUCH_ITEM"; + case AP4_ERROR_OUT_OF_RANGE: return "AP4_ERROR_OUT_OF_RANGE"; + case AP4_ERROR_INTERNAL: return "AP4_ERROR_INTERNAL"; + case AP4_ERROR_INVALID_STATE: return "AP4_ERROR_INVALID_STATE"; + case AP4_ERROR_LIST_EMPTY: return "AP4_ERROR_LIST_EMPTY"; + case AP4_ERROR_LIST_OPERATION_ABORTED: return "AP4_ERROR_LIST_OPERATION_ABORTED"; + case AP4_ERROR_INVALID_RTP_CONSTRUCTOR_TYPE: return "AP4_ERROR_INVALID_RTP_CONSTRUCTOR_TYPE"; + case AP4_ERROR_NOT_SUPPORTED: return "AP4_ERROR_NOT_SUPPORTED"; + case AP4_ERROR_INVALID_TRACK_TYPE: return "AP4_ERROR_INVALID_TRACK_TYPE"; + case AP4_ERROR_INVALID_RTP_PACKET_EXTRA_DATA: return "AP4_ERROR_INVALID_RTP_PACKET_EXTRA_DATA"; + case AP4_ERROR_BUFFER_TOO_SMALL: return "AP4_ERROR_BUFFER_TOO_SMALL"; + case AP4_ERROR_NOT_ENOUGH_DATA: return "AP4_ERROR_NOT_ENOUGH_DATA"; + default: return "UNKNOWN"; + } +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4String.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4String.cpp new file mode 100644 index 000000000..f93422416 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4String.cpp @@ -0,0 +1,181 @@ +/***************************************************************** +| +| AP4 - Strings +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| +****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4String.h" +#include "Ap4Types.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| AP4_String::EmptyString ++---------------------------------------------------------------------*/ +char AP4_String::EmptyString = 0; + +/*---------------------------------------------------------------------- +| AP4_String::AP4_String ++---------------------------------------------------------------------*/ +AP4_String::AP4_String() : m_Chars(&EmptyString), m_Length(0) {} + +/*---------------------------------------------------------------------- +| AP4_String::AP4_String ++---------------------------------------------------------------------*/ +AP4_String::AP4_String(const char* s) { + if (s == NULL) { + m_Chars = &EmptyString; + m_Length = 0; + return; + } + m_Length = (AP4_Size)AP4_StringLength(s); + m_Chars = new char[m_Length+1]; + AP4_CopyMemory(m_Chars, s, m_Length+1); +} + +/*---------------------------------------------------------------------- +| AP4_String::AP4_String ++---------------------------------------------------------------------*/ +AP4_String::AP4_String(const char* s, AP4_Size size) : + m_Chars(new char[size+1]), + m_Length(size) +{ + m_Chars[size] = 0; + AP4_CopyMemory(m_Chars, s, size); +} + +/*---------------------------------------------------------------------- +| AP4_String::AP4_String ++---------------------------------------------------------------------*/ +AP4_String::AP4_String(const AP4_String& s) { + m_Length = s.m_Length; + m_Chars = new char[m_Length+1]; + AP4_CopyMemory(m_Chars, s.m_Chars, m_Length+1); +} + +/*---------------------------------------------------------------------- +| AP4_String::AP4_String ++---------------------------------------------------------------------*/ +AP4_String::AP4_String(AP4_Size size) { + m_Length = size; + m_Chars = new char[m_Length+1]; + for (unsigned int i=0; i<size+1; i++) m_Chars[i] = 0; +} + +/*---------------------------------------------------------------------- +| AP4_String::~AP4_String ++---------------------------------------------------------------------*/ +AP4_String::~AP4_String() +{ + if (m_Chars != &EmptyString) delete[] m_Chars; +} + +/*---------------------------------------------------------------------- +| AP4_String::operator= ++---------------------------------------------------------------------*/ +const AP4_String& +AP4_String::operator=(const AP4_String& s) +{ + if (&s == this) return s; + if (m_Chars != &EmptyString) delete[] m_Chars; + m_Length = s.m_Length; + m_Chars = new char[m_Length+1]; + AP4_CopyMemory(m_Chars, s.m_Chars, m_Length+1); + + return *this; +} + +/*---------------------------------------------------------------------- +| AP4_String::operator= ++---------------------------------------------------------------------*/ +const AP4_String& +AP4_String::operator=(const char* s) +{ + if (s == NULL) { + if (m_Chars != &EmptyString) delete[] m_Chars; + m_Chars = &EmptyString; + m_Length = 0; + } else { + Assign(s, (AP4_Size)AP4_StringLength(s)); + } + + return *this; +} + +/*---------------------------------------------------------------------- +| AP4_String::operator== ++---------------------------------------------------------------------*/ +bool +AP4_String::operator==(const AP4_String& s) const +{ + if (m_Length != s.m_Length) return false; + for (unsigned int i=0; i<m_Length; i++) { + if (m_Chars[i] != s.m_Chars[i]) return false; + } + return true; +} + + +/*---------------------------------------------------------------------- +| AP4_String::operator== ++---------------------------------------------------------------------*/ +bool +AP4_String::operator==(const char* s) const +{ + AP4_Size s_length = (AP4_Size)AP4_StringLength(s); + if (m_Length != s_length) return false; + for (unsigned int i=0; i<s_length; i++) { + if (m_Chars[i] != s[i]) return false; + } + return true; +} + +/*---------------------------------------------------------------------- +| AP4_String::Assign ++---------------------------------------------------------------------*/ +void +AP4_String::Assign(const char* s, AP4_Size size) +{ + if (m_Chars != &EmptyString) delete[] m_Chars; + m_Length = size; + m_Chars = new char[m_Length+1]; + AP4_CopyMemory(m_Chars, s, m_Length); + m_Chars[size] = '\0'; +} + +/*---------------------------------------------------------------------- +| AP4_String::Find ++---------------------------------------------------------------------*/ +int +AP4_String::Find(char c, unsigned int start) const +{ + const char* chars = GetChars(); + for (unsigned int i=start; i<m_Length; i++) { + if (chars[i] == c) return i; + } + return -1; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4String.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4String.h new file mode 100644 index 000000000..f1d81ef06 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4String.h @@ -0,0 +1,81 @@ +/***************************************************************** +| +| AP4 - Strings +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| +****************************************************************/ + +#ifndef _AP4_STRING_H_ +#define _AP4_STRING_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Config.h" +#include "Ap4Types.h" + +/*---------------------------------------------------------------------- +| AP4_String ++---------------------------------------------------------------------*/ +class AP4_String +{ +public: + // constructors + AP4_String(); + AP4_String(const char* s); + AP4_String(const char* s, AP4_Size size); + AP4_String(const AP4_String& s); + explicit AP4_String(AP4_Size size); + + // destructor + ~AP4_String(); + + // operators + const AP4_String& operator=(const AP4_String& s); + const AP4_String& operator=(const char* s); + char operator[](unsigned int index) const { + return m_Chars[index]; + } + bool operator==(const AP4_String& s) const; + bool operator!=(const AP4_String& s) const { return !(*this == s); } + bool operator==(const char* s) const; + bool operator!=(const char* s) const { return !(*this == s); } + + // methods + AP4_Size GetLength() const { return m_Length; } + const char* GetChars() const { return m_Chars; } + char* UseChars() { return m_Chars; } + void Assign(const char* chars, AP4_Size size); + int Find(char c, unsigned int start = 0) const; + +private: + // class members + static char EmptyString; + + // members + char* m_Chars; + AP4_Size m_Length; +}; + +#endif // _AP4_STRING_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TfhdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TfhdAtom.cpp new file mode 100644 index 000000000..b169e277f --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TfhdAtom.cpp @@ -0,0 +1,169 @@ +/***************************************************************** +| +| AP4 - tfhd Atoms +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4TfhdAtom.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| AP4_TfhdAtom::Create ++---------------------------------------------------------------------*/ +AP4_TfhdAtom* +AP4_TfhdAtom::Create(AP4_Size size, AP4_ByteStream& stream) +{ + AP4_UI32 version; + AP4_UI32 flags; + if (AP4_FAILED(AP4_Atom::ReadFullHeader(stream, version, flags))) return NULL; + if (version > 0) return NULL; + if (size != ComputeSize(flags)) return NULL; + return new AP4_TfhdAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_TfhdAtom::ComputeSize ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_TfhdAtom::ComputeSize(AP4_UI32 flags) +{ + AP4_UI32 size = AP4_FULL_ATOM_HEADER_SIZE+4; + if (flags & AP4_TFHD_FLAG_BASE_DATA_OFFSET_PRESENT) size += 8; + if (flags & AP4_TFHD_FLAG_SAMPLE_DESCRIPTION_INDEX_PRESENT) size += 4; + if (flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_DURATION_PRESENT) size += 4; + if (flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_SIZE_PRESENT) size += 4; + if (flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_FLAGS_PRESENT) size += 4; + return size; +} + +/*---------------------------------------------------------------------- +| AP4_TfhdAtom::AP4_TfhdAtom ++---------------------------------------------------------------------*/ +AP4_TfhdAtom::AP4_TfhdAtom(AP4_UI32 flags, + AP4_UI32 track_id, + AP4_UI64 base_data_offset, + AP4_UI32 sample_description_index, + AP4_UI32 default_sample_duration, + AP4_UI32 default_sample_size, + AP4_UI32 default_sample_flags) : + AP4_Atom(AP4_ATOM_TYPE_TFHD, ComputeSize(flags), 0, flags), + m_TrackId(track_id), + m_BaseDataOffset(base_data_offset), + m_SampleDescriptionIndex(sample_description_index), + m_DefaultSampleDuration(default_sample_duration), + m_DefaultSampleSize(default_sample_size), + m_DefaultSampleFlags(default_sample_flags) +{ +} + +/*---------------------------------------------------------------------- +| AP4_TfhdAtom::AP4_TfhdAtom ++---------------------------------------------------------------------*/ +AP4_TfhdAtom::AP4_TfhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_TFHD, size, version, flags) +{ + stream.ReadUI32(m_TrackId); + if (flags & AP4_TFHD_FLAG_BASE_DATA_OFFSET_PRESENT) { + stream.ReadUI64(m_BaseDataOffset); + } + if (flags & AP4_TFHD_FLAG_SAMPLE_DESCRIPTION_INDEX_PRESENT) { + stream.ReadUI32(m_SampleDescriptionIndex); + } + if (flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_DURATION_PRESENT) { + stream.ReadUI32(m_DefaultSampleDuration); + } + if (flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_SIZE_PRESENT) { + stream.ReadUI32(m_DefaultSampleSize); + } + if (flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_FLAGS_PRESENT) { + stream.ReadUI32(m_DefaultSampleFlags); + } +} + +/*---------------------------------------------------------------------- +| AP4_TfhdAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TfhdAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + result = stream.WriteUI32(m_TrackId); + if (AP4_FAILED(result)) return result; + if (m_Flags & AP4_TFHD_FLAG_BASE_DATA_OFFSET_PRESENT) { + result = stream.WriteUI64(m_BaseDataOffset); + if (AP4_FAILED(result)) return result; + } + if (m_Flags & AP4_TFHD_FLAG_SAMPLE_DESCRIPTION_INDEX_PRESENT) { + result = stream.WriteUI32(m_SampleDescriptionIndex); + if (AP4_FAILED(result)) return result; + } + if (m_Flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_DURATION_PRESENT) { + stream.WriteUI32(m_DefaultSampleDuration); + if (AP4_FAILED(result)) return result; + } + if (m_Flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_SIZE_PRESENT) { + stream.WriteUI32(m_DefaultSampleSize); + if (AP4_FAILED(result)) return result; + } + if (m_Flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_FLAGS_PRESENT) { + stream.WriteUI32(m_DefaultSampleFlags); + if (AP4_FAILED(result)) return result; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_TfhdAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TfhdAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("track ID", m_TrackId); + if (m_Flags & AP4_TFHD_FLAG_BASE_DATA_OFFSET_PRESENT) { + inspector.AddField("base data offset", m_BaseDataOffset); + } + if (m_Flags & AP4_TFHD_FLAG_SAMPLE_DESCRIPTION_INDEX_PRESENT) { + inspector.AddField("sample description index", m_SampleDescriptionIndex); + } + if (m_Flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_DURATION_PRESENT) { + inspector.AddField("default sample duration", m_DefaultSampleDuration); + } + if (m_Flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_SIZE_PRESENT) { + inspector.AddField("default sample size", m_DefaultSampleSize); + } + if (m_Flags & AP4_TFHD_FLAG_DEFAULT_SAMPLE_FLAGS_PRESENT) { + inspector.AddField("default sample flags", m_DefaultSampleFlags, AP4_AtomInspector::HINT_HEX ); + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TfhdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TfhdAtom.h new file mode 100644 index 000000000..cf07a5335 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TfhdAtom.h @@ -0,0 +1,97 @@ +/***************************************************************** +| +| AP4 - tfhd Atoms +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ + +#ifndef _AP4_TFHD_ATOM_H_ +#define _AP4_TFHD_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_TFHD_FLAG_BASE_DATA_OFFSET_PRESENT = 0x00001; +const AP4_UI32 AP4_TFHD_FLAG_SAMPLE_DESCRIPTION_INDEX_PRESENT = 0x00002; +const AP4_UI32 AP4_TFHD_FLAG_DEFAULT_SAMPLE_DURATION_PRESENT = 0x00008; +const AP4_UI32 AP4_TFHD_FLAG_DEFAULT_SAMPLE_SIZE_PRESENT = 0x00010; +const AP4_UI32 AP4_TFHD_FLAG_DEFAULT_SAMPLE_FLAGS_PRESENT = 0x00020; +const AP4_UI32 AP4_TFHD_FLAG_DURATION_IS_EMPTY = 0x10000; + +/*---------------------------------------------------------------------- +| AP4_TfhdAtom ++---------------------------------------------------------------------*/ +class AP4_TfhdAtom : public AP4_Atom +{ +public: + // class methods + static AP4_TfhdAtom* Create(AP4_Size size, AP4_ByteStream& stream); + static AP4_UI32 ComputeSize(AP4_UI32 flags); + + // methods + AP4_TfhdAtom(AP4_UI32 flags, + AP4_UI32 track_id, + AP4_UI64 base_data_offset, + AP4_UI32 sample_description_index, + AP4_UI32 default_sample_duration, + AP4_UI32 default_sample_size, + AP4_UI32 default_sample_flags); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + AP4_UI32 GetTrackId() { return m_TrackId; } + void SetTrackId(AP4_UI32 track_id) { m_TrackId = track_id; } + AP4_UI64 GetBaseDataOffset() { return m_BaseDataOffset; } + void SetBaseDataOffset(AP4_UI64 offset) { m_BaseDataOffset = offset; } + AP4_UI32 GetSampleDescriptionIndex() { return m_SampleDescriptionIndex; } + void SetSampleDescriptionIndex(AP4_UI32 indx) { m_SampleDescriptionIndex = indx; } + AP4_UI32 GetDefaultSampleDuration() { return m_DefaultSampleDuration; } + void SetDefaultSampleDuration(AP4_UI32 duration) { m_DefaultSampleDuration = duration; } + AP4_UI32 GetDefaultSampleSize() { return m_DefaultSampleSize; } + void SetDefaultSampleSize(AP4_UI32 size) { m_DefaultSampleSize = size; } + AP4_UI32 GetDefaultSampleFlags() { return m_DefaultSampleFlags; } + void SetDefaultSampleFlags(AP4_UI32 flags) { m_DefaultSampleFlags = flags; } + +private: + // methods + AP4_TfhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI32 m_TrackId; + AP4_UI64 m_BaseDataOffset; + AP4_UI32 m_SampleDescriptionIndex; + AP4_UI32 m_DefaultSampleDuration; + AP4_UI32 m_DefaultSampleSize; + AP4_UI32 m_DefaultSampleFlags; +}; + +#endif // _AP4_TFHD_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrunAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrunAtom.cpp new file mode 100644 index 000000000..f21164ced --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrunAtom.cpp @@ -0,0 +1,202 @@ +/***************************************************************** +| +| AP4 - trun Atoms +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4TrunAtom.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| AP4_TrunAtom::Create ++---------------------------------------------------------------------*/ +AP4_TrunAtom* +AP4_TrunAtom::Create(AP4_Size size, AP4_ByteStream& stream) +{ + AP4_UI32 version; + AP4_UI32 flags; + if (AP4_FAILED(AP4_Atom::ReadFullHeader(stream, version, flags))) return NULL; + if (version > 0) return NULL; + return new AP4_TrunAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_TrunAtom::ComputeSize ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_TrunAtom::ComputeEntrySize(AP4_UI32 flags) +{ + AP4_UI32 size = 0; + if (flags & AP4_TRUN_FLAG_SAMPLE_DURATION_PRESENT) size += 4; + if (flags & AP4_TRUN_FLAG_SAMPLE_SIZE_PRESENT) size += 4; + if (flags & AP4_TRUN_FLAG_SAMPLE_FLAGS_PRESENT) size += 4; + if (flags & AP4_TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT) size += 4; + return size; +} + +/*---------------------------------------------------------------------- +| AP4_TrunAtom::AP4_TrunAtom ++---------------------------------------------------------------------*/ +AP4_TrunAtom::AP4_TrunAtom(AP4_UI32 flags, + AP4_SI32 data_offset, + AP4_UI32 first_sample_flags) : + AP4_Atom(AP4_ATOM_TYPE_TRUN, AP4_FULL_ATOM_HEADER_SIZE+4, 0, flags), + m_DataOffset(data_offset), + m_FirstSampleFlags(first_sample_flags) +{ + if (flags & AP4_TRUN_FLAG_DATA_OFFSET_PRESENT) m_Size32 += 4; + if (flags & AP4_TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT) m_Size32 += 4; +} + +/*---------------------------------------------------------------------- +| AP4_TrunAtom::AP4_TrunAtom ++---------------------------------------------------------------------*/ +AP4_TrunAtom::AP4_TrunAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_TRUN, size, version, flags) +{ + AP4_UI32 sample_count = 0; + stream.ReadUI32(sample_count); + if (flags & AP4_TRUN_FLAG_DATA_OFFSET_PRESENT) { + AP4_UI32 offset = 0; + stream.ReadUI32(offset); + m_DataOffset = (AP4_SI32)offset; + } + if (flags & AP4_TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT) { + stream.ReadUI32(m_FirstSampleFlags); + } + m_Entries.SetItemCount(sample_count); + for (unsigned int i=0; i<sample_count; i++) { + if (flags & AP4_TRUN_FLAG_SAMPLE_DURATION_PRESENT) { + stream.ReadUI32(m_Entries[i].sample_duration); + } + if (flags & AP4_TRUN_FLAG_SAMPLE_SIZE_PRESENT) { + stream.ReadUI32(m_Entries[i].sample_size); + } + if (flags & AP4_TRUN_FLAG_SAMPLE_FLAGS_PRESENT) { + stream.ReadUI32(m_Entries[i].sample_flags); + } + if (flags & AP4_TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT) { + stream.ReadUI32(m_Entries[i].sample_composition_time_offset); + } + } +} + +/*---------------------------------------------------------------------- +| AP4_TrunAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrunAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + result = stream.WriteUI32(m_Entries.ItemCount()); + if (AP4_FAILED(result)) return result; + if (m_Flags & AP4_TRUN_FLAG_DATA_OFFSET_PRESENT) { + result = stream.WriteUI32((AP4_UI32)m_DataOffset); + if (AP4_FAILED(result)) return result; + } + if (m_Flags & AP4_TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT) { + result = stream.WriteUI32(m_FirstSampleFlags); + if (AP4_FAILED(result)) return result; + } + AP4_UI32 sample_count = m_Entries.ItemCount(); + for (unsigned int i=0; i<sample_count; i++) { + if (m_Flags & AP4_TRUN_FLAG_SAMPLE_DURATION_PRESENT) { + result = stream.WriteUI32(m_Entries[i].sample_duration); + if (AP4_FAILED(result)) return result; + } + if (m_Flags & AP4_TRUN_FLAG_SAMPLE_SIZE_PRESENT) { + result = stream.WriteUI32(m_Entries[i].sample_size); + if (AP4_FAILED(result)) return result; + } + if (m_Flags & AP4_TRUN_FLAG_SAMPLE_FLAGS_PRESENT) { + result = stream.WriteUI32(m_Entries[i].sample_flags); + if (AP4_FAILED(result)) return result; + } + if (m_Flags & AP4_TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT) { + stream.WriteUI32(m_Entries[i].sample_composition_time_offset); + if (AP4_FAILED(result)) return result; + } + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_TrunAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrunAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("sample count", m_Entries.ItemCount()); + if (m_Flags & AP4_TRUN_FLAG_DATA_OFFSET_PRESENT) { + inspector.AddField("data offset", m_DataOffset); + } + if (m_Flags & AP4_TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT) { + inspector.AddField("first sample flags", m_FirstSampleFlags, AP4_AtomInspector::HINT_HEX); + } + if (inspector.GetVerbosity() >= 1) { + AP4_UI32 sample_count = m_Entries.ItemCount(); + for (unsigned int i=0; i<sample_count; i++) { + char header[32]; + AP4_FormatString(header, sizeof(header), "entry %04d", i); + char v0[32]; + char v1[32]; + char v2[32]; + char v3[64]; + const char* s0 = ""; + const char* s1 = ""; + const char* s2 = ""; + const char* s3 = ""; + if (m_Flags & AP4_TRUN_FLAG_SAMPLE_DURATION_PRESENT) { + AP4_FormatString(v0, sizeof(v0), "sample duration:%d", m_Entries[i].sample_duration); + s0 = v0; + } + if (m_Flags & AP4_TRUN_FLAG_SAMPLE_SIZE_PRESENT) { + AP4_FormatString(v1, sizeof(v1), "sample size:%d", m_Entries[i].sample_size); + s1 = v1; + } + if (m_Flags & AP4_TRUN_FLAG_SAMPLE_FLAGS_PRESENT) { + AP4_FormatString(v2, sizeof(v2), "sample flags:%x", m_Entries[i].sample_flags); + s2 = v2; + } + if (m_Flags & AP4_TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT) { + AP4_FormatString(v3, sizeof(v3), "sample composition time offset:%d", m_Entries[i].sample_composition_time_offset); + s3 = v3; + } + char value[128]; + AP4_FormatString(value, sizeof(value), "%s %s %s %s", s0, s1, s2, s3); + inspector.AddField(header, value); + } + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrunAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrunAtom.h new file mode 100644 index 000000000..370493c1c --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrunAtom.h @@ -0,0 +1,86 @@ +/***************************************************************** +| +| AP4 - trun Atoms +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ + +#ifndef _AP4_TRUN_ATOM_H_ +#define _AP4_TRUN_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" +#include "Ap4Array.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_TRUN_FLAG_DATA_OFFSET_PRESENT = 0x0001; +const AP4_UI32 AP4_TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT = 0x0004; +const AP4_UI32 AP4_TRUN_FLAG_SAMPLE_DURATION_PRESENT = 0x0100; +const AP4_UI32 AP4_TRUN_FLAG_SAMPLE_SIZE_PRESENT = 0x0200; +const AP4_UI32 AP4_TRUN_FLAG_SAMPLE_FLAGS_PRESENT = 0x0400; +const AP4_UI32 AP4_TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT = 0x0800; + +/*---------------------------------------------------------------------- +| AP4_TrunAtom ++---------------------------------------------------------------------*/ +class AP4_TrunAtom : public AP4_Atom +{ +public: + // types + struct Entry { + AP4_UI32 sample_duration; + AP4_UI32 sample_size; + AP4_UI32 sample_flags; + AP4_UI32 sample_composition_time_offset; + }; + + // class methods + static AP4_TrunAtom* Create(AP4_Size size, AP4_ByteStream& stream); + static AP4_UI32 ComputeEntrySize(AP4_UI32 flags); + + // methods + AP4_TrunAtom(AP4_UI32 flags, + AP4_SI32 data_offset, + AP4_UI32 first_sample_flags); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // methods + AP4_TrunAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_SI32 m_DataOffset; + AP4_UI32 m_FirstSampleFlags; + AP4_Array<Entry> m_Entries; +}; + +#endif // _AP4_TRUN_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UuidAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UuidAtom.cpp new file mode 100644 index 000000000..e1061b80e --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UuidAtom.cpp @@ -0,0 +1,133 @@ +/***************************************************************** +| +| AP4 - UUID Atoms +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4UuidAtom.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| AP4_UuidAtom::AP4_UuidAtom ++---------------------------------------------------------------------*/ +AP4_UuidAtom::AP4_UuidAtom(AP4_UI64 size, AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_UUID, size), + m_SourceStream(&stream) +{ + // read the uuid + stream.Read(m_Uuid, 16); + + // store source stream position + stream.Tell(m_SourcePosition); + + // keep a reference to the source stream + m_SourceStream->AddReference(); +} + +/*---------------------------------------------------------------------- +| AP4_UuidAtom::~AP4_UuidAtom ++---------------------------------------------------------------------*/ +AP4_UuidAtom::~AP4_UuidAtom() +{ + // release the source stream reference + if (m_SourceStream) { + m_SourceStream->Release(); + } +} + +/*---------------------------------------------------------------------- +| AP4_NibbleHex ++---------------------------------------------------------------------*/ +static char +AP4_NibbleHex(unsigned int nibble) +{ + if (nibble < 10) { + return '0'+nibble; + } else if (nibble < 16) { + return 'A'+(nibble-10); + } else { + return ' '; + } +} + +/*---------------------------------------------------------------------- +| AP4_UuidAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_UuidAtom::InspectFields(AP4_AtomInspector& inspector) +{ + char uuid[37]; + uuid[36] = '\0'; + char* dst = uuid; + for (unsigned int i=0; i<16; i++) { + *dst++ = AP4_NibbleHex(m_Uuid[i]>>4); + *dst++ = AP4_NibbleHex(m_Uuid[i]&0x0F); + if (i == 5 || i == 7 || i == 9 || i == 11) *dst++ = '-'; + } + inspector.AddField("uuid", uuid); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_UuidAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_UuidAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // write uuid + stream.Write(m_Uuid, 16); + + // check that we have a source stream + // and a normal size + if (m_SourceStream == NULL || GetSize() < 8+16) { + return AP4_FAILURE; + } + + // remember the source position + AP4_Position position; + m_SourceStream->Tell(position); + + // seek into the source at the stored offset + result = m_SourceStream->Seek(m_SourcePosition); + if (AP4_FAILED(result)) return result; + + // copy the source stream to the output + AP4_UI64 payload_size = GetSize()-GetHeaderSize()-16; + result = m_SourceStream->CopyTo(stream, payload_size); + if (AP4_FAILED(result)) return result; + + // restore the original stream position + m_SourceStream->Seek(position); + + return AP4_SUCCESS; +} + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UuidAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UuidAtom.h new file mode 100644 index 000000000..52826378d --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UuidAtom.h @@ -0,0 +1,66 @@ +/***************************************************************** +| +| AP4 - UUID Atoms +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ +/** +* @file +* @brief UUID Atoms +*/ + +#ifndef _AP4_UUID_ATOM_H_ +#define _AP4_UUID_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" +#include "Ap4ByteStream.h" + +/*---------------------------------------------------------------------- +| AP4_UuidAtom ++---------------------------------------------------------------------*/ +/** + * Base class for uuid atoms. + */ +class AP4_UuidAtom : public AP4_Atom { +public: + // constructor and destructor + AP4_UuidAtom(AP4_UI64 size, + AP4_ByteStream& stream); + ~AP4_UuidAtom(); + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +protected: + // members + AP4_UI08 m_Uuid[16]; + AP4_ByteStream* m_SourceStream; + AP4_Position m_SourcePosition; +}; + +#endif // _AP4_UUID_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Version.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Version.h new file mode 100644 index 000000000..0af2c4091 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Version.h @@ -0,0 +1,43 @@ +/***************************************************************** +| +| AP4 - Version Numbers +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This file is part of Bento4/AP4 (MP4 Atom Processing Library). +| +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Unless you have obtained Bento4 under a difference license, +| this version of Bento4 is Bento4|GPL. +| Bento4|GPL is free software; you can redistribute it and/or modify +| it under the terms of the GNU General Public License as published by +| the Free Software Foundation; either version 2, or (at your option) +| any later version. +| +| Bento4|GPL is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with Bento4|GPL; see the file COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| +****************************************************************/ + +#ifndef _AP4_VERSION_H_ +#define _AP4_VERSION_H_ + +/*---------------------------------------------------------------------- +| version constants ++---------------------------------------------------------------------*/ +/** + * Version number of the SDK + */ +#define AP4_VERSION 0x01010100 +#define AP4_VERSION_STRING "1.1.1.0" + +#endif // _AP4_VERSION_H_ |