Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpec-Chum <spec-chum@users.sourceforge.net>2010-01-01 22:16:07 +0300
committerSpec-Chum <spec-chum@users.sourceforge.net>2010-01-01 22:16:07 +0300
commite6614272516c4582a1fcf01b5773e379809b86b5 (patch)
treee562a85b0361205508e596d6342c2e1c8d59e9aa /src/filters/parser
parente903fa492b27da8d505057b1722dbb35e2ec47e4 (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')
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap48bdlAtom.cpp127
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Protection.cpp1184
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Protection.h451
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Results.cpp68
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4String.cpp181
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4String.h81
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TfhdAtom.cpp169
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TfhdAtom.h97
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrunAtom.cpp202
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrunAtom.h86
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UuidAtom.cpp133
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UuidAtom.h66
-rw-r--r--src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Version.h43
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_