diff options
author | Casimir666 <casimir666@users.sourceforge.net> | 2010-01-01 20:32:26 +0300 |
---|---|---|
committer | Casimir666 <casimir666@users.sourceforge.net> | 2010-01-01 20:32:26 +0300 |
commit | e903fa492b27da8d505057b1722dbb35e2ec47e4 (patch) | |
tree | 4184e2fbe7f7d84efb7e286edfd4d436c8cce02d /src/filters/parser/mp4splitter | |
parent | 23a091aa5fb93b6727c3ef3f11905ded5b1b57b2 (diff) |
Updated : MP4 splitter updated to latest Bento4 library
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@1460 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/parser/mp4splitter')
184 files changed, 26475 insertions, 13109 deletions
diff --git a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AdtsParser.cpp b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AdtsParser.cpp index c5f050d0c..1e46bbcee 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AdtsParser.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AdtsParser.cpp @@ -1,23 +1,39 @@ - /***************************************************************** | -| File: Ap4AdtsParser.c +| AP4 - AAC ADTS Parser +| +| 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. | -| AP4 - ADTS Parser +| 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. | -| (c) 2005 Gilles Boccon-Gibod -| Author: Gilles Boccon-Gibod (bok@bok.net) +| 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 +| includes +---------------------------------------------------------------------*/ #include "Ap4BitStream.h" #include "Ap4AdtsParser.h" /*---------------------------------------------------------------------- -| constants +| constants +---------------------------------------------------------------------*/ #define AP4_ADTS_HEADER_SIZE 7 @@ -46,7 +62,7 @@ AP4_AdtsSamplingFrequencyTable[16] = }; /*----------------------------------------------------------------------+ -| AP4_AdtsHeader::AP4_AdtsHeader +| AP4_AdtsHeader::AP4_AdtsHeader +----------------------------------------------------------------------*/ AP4_AdtsHeader::AP4_AdtsHeader(const AP4_UI08* bytes) { @@ -65,7 +81,7 @@ AP4_AdtsHeader::AP4_AdtsHeader(const AP4_UI08* bytes) } /*----------------------------------------------------------------------+ -| AP4_AdtsHeader::MatchFixed +| AP4_AdtsHeader::MatchFixed | | Check that two fixed headers are the same | @@ -84,7 +100,7 @@ AP4_AdtsHeader::MatchFixed(unsigned char* a, unsigned char* b) } /*----------------------------------------------------------------------+ -| AP4_AdtsHeader::Check +| AP4_AdtsHeader::Check +----------------------------------------------------------------------*/ AP4_Result AP4_AdtsHeader::Check() @@ -103,21 +119,21 @@ AP4_AdtsHeader::Check() } /*----------------------------------------------------------------------+ -| AP4_AdtsParser::AP4_AdtsParser +| AP4_AdtsParser::AP4_AdtsParser +----------------------------------------------------------------------*/ AP4_AdtsParser::AP4_AdtsParser() { } /*----------------------------------------------------------------------+ -| AP4_AdtsParser::~AP4_AdtsParser +| AP4_AdtsParser::~AP4_AdtsParser +----------------------------------------------------------------------*/ AP4_AdtsParser::~AP4_AdtsParser() { } /*----------------------------------------------------------------------+ -| AP4_AdtsParser::Reset +| AP4_AdtsParser::Reset +----------------------------------------------------------------------*/ AP4_Result AP4_AdtsParser::Reset() @@ -128,7 +144,7 @@ AP4_AdtsParser::Reset() } /*----------------------------------------------------------------------+ -| AP4_AdtsParser::Feed +| AP4_AdtsParser::Feed +----------------------------------------------------------------------*/ AP4_Result AP4_AdtsParser::Feed(const AP4_UI08* buffer, @@ -156,7 +172,7 @@ AP4_AdtsParser::Feed(const AP4_UI08* buffer, } /*----------------------------------------------------------------------+ -| AP4_AdtsParser::FindHeader +| AP4_AdtsParser::FindHeader +----------------------------------------------------------------------*/ AP4_Result AP4_AdtsParser::FindHeader(AP4_UI08* header) @@ -184,7 +200,7 @@ AP4_AdtsParser::FindHeader(AP4_UI08* header) } /*----------------------------------------------------------------------+ -| AP4_AdtsParser::FindFrame +| AP4_AdtsParser::FindFrame +----------------------------------------------------------------------*/ AP4_Result AP4_AdtsParser::FindFrame(AP4_AacFrame& frame) @@ -280,7 +296,7 @@ fail: } /*----------------------------------------------------------------------+ -| AP4_AdtsParser::GetBytesFree +| AP4_AdtsParser::GetBytesFree +----------------------------------------------------------------------*/ AP4_Size AP4_AdtsParser::GetBytesFree() @@ -291,7 +307,7 @@ AP4_AdtsParser::GetBytesFree() /*----------------------------------------------------------------------+ -| AP4_AdtsParser::GetBytesAvailable +| AP4_AdtsParser::GetBytesAvailable +----------------------------------------------------------------------*/ AP4_Size AP4_AdtsParser::GetBytesAvailable() diff --git a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AdtsParser.h b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AdtsParser.h index 606fe8919..1db5f27b4 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AdtsParser.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AdtsParser.h @@ -1,30 +1,47 @@ /***************************************************************** | -| File: Ap4AdtsParser.h +| AP4 - AAC ADTS Parser | -| AP4 - ADTS Parser +| Copyright 2002-2008 Axiomatic Systems, LLC | -| (c) 2005 Gilles Boccon-Gibod -| Author: Gilles Boccon-Gibod (bok@bok.net) | - ****************************************************************/ +| 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_ADTS_PARSER_H_ #define _AP4_ADTS_PARSER_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Types.h" #include "Ap4BitStream.h" /*---------------------------------------------------------------------- -| constants +| constants +---------------------------------------------------------------------*/ extern const unsigned long AP4_AdtsSamplingFrequencyTable[16]; /*---------------------------------------------------------------------- -| types +| types +---------------------------------------------------------------------*/ class AP4_AdtsHeader { public: diff --git a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AvcParser.cpp b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AvcParser.cpp new file mode 100644 index 000000000..d40883578 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AvcParser.cpp @@ -0,0 +1,219 @@ +/***************************************************************** +| +| AP4 - AVC Parser +| +| 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 "Ap4AvcParser.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| AP4_AvcParser::NaluTypeName ++---------------------------------------------------------------------*/ +const char* +AP4_AvcParser::NaluTypeName(unsigned int nalu_type) +{ + switch (nalu_type) { + case 0: return "Unspecified"; + case 1: return "Coded slice of a non-IDR picture"; + case 2: return "Coded slice data partition A"; + case 3: return "Coded slice data partition B"; + case 4: return "Coded slice data partition C"; + case 5: return "Coded slice of an IDR picture"; + case 6: return "Supplemental enhancement information (SEI)"; + case 7: return "Sequence parameter set"; + case 8: return "Picture parameter set"; + case 9: return "Access unit delimiter"; + case 10: return "End of sequence"; + case 11: return "End of stream"; + case 12: return "Filler data"; + case 13: return "Sequence parameter set extension"; + case 14: return "Prefix NAL unit in scalable extension"; + case 15: return "Subset sequence parameter set"; + case 19: return "Coded slice of an auxiliary coded picture without partitioning"; + case 20: return "Coded slice in scalable extension"; + default: return NULL; + } +} + +/*---------------------------------------------------------------------- +| AP4_AvcParser::PrimaryPicTypeName ++---------------------------------------------------------------------*/ +const char* +AP4_AvcParser::PrimaryPicTypeName(unsigned int primary_pic_type) +{ + switch (primary_pic_type) { + case 0: return "I Frame"; + case 1: return "P Frame"; + case 2: return "B Frame"; + default: return NULL; + } +} + +/*---------------------------------------------------------------------- +| AP4_AvcParser::SliceTypeName ++---------------------------------------------------------------------*/ +const char* +AP4_AvcParser::SliceTypeName(unsigned int slice_type) +{ + switch (slice_type) { + case 0: return "P"; + case 1: return "B"; + case 2: return "I"; + case 3: return "SP"; + case 4: return "SI"; + case 5: return "P"; + case 6: return "B"; + case 7: return "I"; + case 8: return "SP"; + case 9: return "SI"; + default: return NULL; + } +} + +/*---------------------------------------------------------------------- +| AP4_AvcParser::AP4_AvcParser ++---------------------------------------------------------------------*/ +AP4_AvcParser::AP4_AvcParser() : + m_State(STATE_RESET), + m_ZeroTrail(0) +{ +} + +/*---------------------------------------------------------------------- +| AP4_AvcParser::Feed ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AvcParser::Feed(const void* data, + AP4_Size data_size, + AP4_Size& bytes_consumed, + const AP4_DataBuffer*& nalu, + bool is_eos) +{ + // default return values + nalu = NULL; + bytes_consumed = 0; + + // iterate the state machine + unsigned int data_offset; + unsigned int payload_start = 0; + unsigned int payload_end = 0; + bool found_nalu = false; + for (data_offset=0; data_offset<data_size && !found_nalu; data_offset++) { + unsigned char byte = ((const unsigned char*)data)[data_offset]; + switch (m_State) { + case STATE_RESET: + if (byte == 0) { + m_State = STATE_START_CODE_1; + } + break; + + case STATE_START_CODE_1: + if (byte == 0) { + m_State = STATE_START_CODE_2; + } else { + m_State = STATE_RESET; + } + break; + + case STATE_START_CODE_2: + if (byte == 0) break; + if (byte == 1) { + m_State = STATE_IN_NALU; + m_Buffer.SetDataSize(0); + m_ZeroTrail = 0; + payload_start = payload_end = data_offset+1; + m_Buffer.SetDataSize(0); + } else { + m_State = STATE_RESET; + } + break; + + case STATE_IN_NALU: + if (byte == 0) m_ZeroTrail++; + if (m_ZeroTrail == 2) { + // maybe end of NALU + m_ZeroTrail = 0; + if (byte == 0) { + found_nalu = true; + m_State = STATE_START_CODE_2; + break; + } else if (byte == 1) { + found_nalu = true; + m_State = STATE_RESET; + break; + } else { + // not the end + payload_end += 3; + } + } else if (m_ZeroTrail == 1) { + if (byte != 0) { + payload_end += 2; + m_ZeroTrail = 0; + } + } else { + // continuation of NALU + ++payload_end; + } + break; + } + } + if (is_eos && m_State == STATE_IN_NALU && data_offset == data_size) { + found_nalu = true; + m_ZeroTrail = 0; + m_State = STATE_RESET; + } + if (payload_end > payload_start) { + AP4_Size current_payload_size = m_Buffer.GetDataSize(); + m_Buffer.SetDataSize(m_Buffer.GetDataSize()+(payload_end-payload_start)); + AP4_CopyMemory(((unsigned char *)m_Buffer.UseData())+current_payload_size, + ((const unsigned char*)data)+payload_start, + payload_end-payload_start); + } + + // compute how many bytes we have consumed + bytes_consumed = data_offset; + + // return the NALU if we found one + if (found_nalu) nalu = &m_Buffer; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_AvcParser::Reset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AvcParser::Reset() +{ + m_State = STATE_RESET; + m_ZeroTrail = 0; + m_Buffer.SetDataSize(0); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AvcParser.h b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AvcParser.h new file mode 100644 index 000000000..a84052ed1 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4AvcParser.h @@ -0,0 +1,95 @@ +/***************************************************************** +| +| AP4 - AVC Parser +| +| 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_AVC_PARSER_H_ +#define _AP4_AVC_PARSER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Results.h" +#include "Ap4DataBuffer.h" + +/*---------------------------------------------------------------------- +| AP4_AvcParser ++---------------------------------------------------------------------*/ +class AP4_AvcParser { +public: + static const char* NaluTypeName(unsigned int nalu_type); + static const char* PrimaryPicTypeName(unsigned int primary_pic_type); + static const char* SliceTypeName(unsigned int slice_type); + + AP4_AvcParser(); + + /** + * Feed some data to the parser and look for the next NAL Unit. + * + * @param data: Pointer to the memory buffer with the data to feed. + * @param data_size: Size in bytes of the buffer pointed to by the + * data pointer. + * @param bytes_consumed: Number of bytes from the data buffer that were + * consumed and stored by the parser. + * @param nal: Reference to a pointer to a buffer object that contains + * a NAL unit found in the previously fed data, or a NULL pointer if no + * NAL unit can be found so far. + * @param eos: Boolean flag that indicates if this buffer is the last + * buffer in the stream/file (End Of Stream). + * + * @result: AP4_SUCCESS is the call succeeds, or an error code if it + * fails. + * + * The caller must not feed the same data twice. When this method + * returns, the caller should inspect the value of bytes_consumed and + * advance the input stream source accordingly, such that the next + * buffer passed to this method will be exactly bytes_consumed bytes + * after what was passed in this call. + */ + AP4_Result Feed(const void* data, + AP4_Size data_size, + AP4_Size& bytes_consumed, + const AP4_DataBuffer*& nalu, + bool eos=false); + + /** + * Reset the state of the parser (for example, to parse a new stream). + */ + AP4_Result Reset(); + +private: + enum { + STATE_RESET, + STATE_START_CODE_1, + STATE_START_CODE_2, + STATE_IN_NALU + } m_State; + AP4_Cardinal m_ZeroTrail; + AP4_DataBuffer m_Buffer; +}; + +#endif // _AP4_AVC_PARSER_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4BitStream.cpp b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4BitStream.cpp index 368acc8ec..0e1ebd596 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4BitStream.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4BitStream.cpp @@ -1,26 +1,44 @@ /***************************************************************** | -| File: Ap4BitStream.c +| AP4 - Bitstream Utility | -| AP4 - Bit Streams +| Copyright 2002-2008 Axiomatic Systems, LLC | -| (c) 2004 Gilles Boccon-Gibod -| Author: Gilles Boccon-Gibod (bok@bok.net) | - ****************************************************************/ +| 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. +| +****************************************************************/ /*---------------------------------------------------------------------- -| For efficiency reasons, this bitstream library only handles -| data buffers that are a power of 2 in size +| For efficiency reasons, this bitstream library only handles +| data buffers that are a power of 2 in size +---------------------------------------------------------------------*/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4BitStream.h" +#include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_BitStream::AP4_BitStream +| AP4_BitStream::AP4_BitStream +---------------------------------------------------------------------*/ AP4_BitStream::AP4_BitStream() { @@ -29,7 +47,7 @@ AP4_BitStream::AP4_BitStream() } /*---------------------------------------------------------------------- -| AP4_BitStream::~AP4_BitStream +| AP4_BitStream::~AP4_BitStream +---------------------------------------------------------------------*/ AP4_BitStream::~AP4_BitStream() { @@ -37,7 +55,7 @@ AP4_BitStream::~AP4_BitStream() } /*---------------------------------------------------------------------- -| AP4_BitStream::Reset +| AP4_BitStream::Reset +---------------------------------------------------------------------*/ AP4_Result AP4_BitStream::Reset() @@ -52,7 +70,7 @@ AP4_BitStream::Reset() } /*---------------------------------------------------------------------- -| AP4_BitStream::ByteAlign +| AP4_BitStream::ByteAlign +---------------------------------------------------------------------*/ AP4_Result AP4_BitStream::ByteAlign() @@ -64,7 +82,7 @@ AP4_BitStream::ByteAlign() } /*---------------------------------------------------------------------- -| AP4_BitStream::GetContiguousBytesFree +| AP4_BitStream::GetContiguousBytesFree +---------------------------------------------------------------------*/ AP4_Size AP4_BitStream::GetContiguousBytesFree() @@ -77,7 +95,7 @@ AP4_BitStream::GetContiguousBytesFree() } /*---------------------------------------------------------------------- -| AP4_BitStream_GetBytesFree +| AP4_BitStream_GetBytesFree +---------------------------------------------------------------------*/ AP4_Size AP4_BitStream::GetBytesFree() @@ -89,7 +107,7 @@ AP4_BitStream::GetBytesFree() } /*----------------------------------------------------------------------+ -| AP4_BitStream::WriteBytes +| AP4_BitStream::WriteBytes +----------------------------------------------------------------------*/ AP4_Result AP4_BitStream::WriteBytes(const AP4_UI08* bytes, @@ -106,18 +124,18 @@ AP4_BitStream::WriteBytes(const AP4_UI08* bytes, /* write the bytes */ if (m_In < m_Out) { - memcpy(m_Buffer+m_In, bytes, byte_count); + AP4_CopyMemory(m_Buffer+m_In, bytes, byte_count); AP4_BITSTREAM_POINTER_ADD(m_In, byte_count); } else { unsigned int chunk = AP4_BITSTREAM_BUFFER_SIZE - m_In; if (chunk > byte_count) chunk = byte_count; - memcpy(m_Buffer+m_In, bytes, chunk); + AP4_CopyMemory(m_Buffer+m_In, bytes, chunk); AP4_BITSTREAM_POINTER_ADD(m_In, chunk); if (chunk != byte_count) { - memcpy(m_Buffer+m_In, - bytes+chunk, byte_count-chunk); + AP4_CopyMemory(m_Buffer+m_In, + bytes+chunk, byte_count-chunk); AP4_BITSTREAM_POINTER_ADD(m_In, byte_count-chunk); } } @@ -126,7 +144,7 @@ AP4_BitStream::WriteBytes(const AP4_UI08* bytes, } /*---------------------------------------------------------------------- -| AP4_BitStream_GetContiguousBytesAvailable +| AP4_BitStream_GetContiguousBytesAvailable +---------------------------------------------------------------------*/ AP4_Size AP4_BitStream::GetContiguousBytesAvailable() @@ -138,7 +156,7 @@ AP4_BitStream::GetContiguousBytesAvailable() } /*---------------------------------------------------------------------- -| AP4_BitStream::GetBytesAvailable +| AP4_BitStream::GetBytesAvailable +---------------------------------------------------------------------*/ AP4_Size AP4_BitStream::GetBytesAvailable() @@ -150,7 +168,7 @@ AP4_BitStream::GetBytesAvailable() } /*----------------------------------------------------------------------+ -| AP4_BitStream::ReadBytes +| AP4_BitStream::ReadBytes +----------------------------------------------------------------------*/ AP4_Result AP4_BitStream::ReadBytes(AP4_UI08* bytes, @@ -171,19 +189,19 @@ AP4_BitStream::ReadBytes(AP4_UI08* bytes, /* Get other bytes */ if (byte_count > 0) { if (m_Out < m_In) { - memcpy(bytes, m_Buffer + m_Out, byte_count); + AP4_CopyMemory(bytes, m_Buffer + m_Out, byte_count); AP4_BITSTREAM_POINTER_ADD(m_Out, byte_count); } else { unsigned int chunk = AP4_BITSTREAM_BUFFER_SIZE - m_Out; if (chunk >= byte_count) chunk = byte_count; - memcpy(bytes, m_Buffer+m_Out, chunk); + AP4_CopyMemory(bytes, m_Buffer+m_Out, chunk); AP4_BITSTREAM_POINTER_ADD(m_Out, chunk); if (chunk != byte_count) { - memcpy(bytes+chunk, - m_Buffer+m_Out, - byte_count-chunk); + AP4_CopyMemory(bytes+chunk, + m_Buffer+m_Out, + byte_count-chunk); AP4_BITSTREAM_POINTER_ADD(m_Out, byte_count-chunk); } } @@ -193,7 +211,7 @@ AP4_BitStream::ReadBytes(AP4_UI08* bytes, } /*----------------------------------------------------------------------+ -| AP4_BitStream::PeekBytes +| AP4_BitStream::PeekBytes +----------------------------------------------------------------------*/ AP4_Result AP4_BitStream::PeekBytes(AP4_UI08* bytes, @@ -217,7 +235,7 @@ AP4_BitStream::PeekBytes(AP4_UI08* bytes, /* Get other bytes */ if (byte_count > 0) { if (m_In > m_Out) { - memcpy(bytes, m_Buffer + m_Out, byte_count); + AP4_CopyMemory(bytes, m_Buffer + m_Out, byte_count); } else { unsigned int out = m_Out; unsigned int chunk = AP4_BITSTREAM_BUFFER_SIZE - out; @@ -225,13 +243,13 @@ AP4_BitStream::PeekBytes(AP4_UI08* bytes, chunk = byte_count; } - memcpy(bytes, m_Buffer+out, chunk); + AP4_CopyMemory(bytes, m_Buffer+out, chunk); AP4_BITSTREAM_POINTER_ADD(out, chunk); if (chunk != byte_count) { - memcpy(bytes+chunk, - m_Buffer+out, - byte_count-chunk); + AP4_CopyMemory(bytes+chunk, + m_Buffer+out, + byte_count-chunk); } } } @@ -240,7 +258,7 @@ AP4_BitStream::PeekBytes(AP4_UI08* bytes, } /*----------------------------------------------------------------------+ -| AP4_BitStream::SkipBytes +| AP4_BitStream::SkipBytes +----------------------------------------------------------------------*/ AP4_Result AP4_BitStream::SkipBytes(AP4_Size byte_count) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4BitStream.h b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4BitStream.h index 0bc71947e..c0bb0566e 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4BitStream.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Codecs/Ap4BitStream.h @@ -1,41 +1,57 @@ /***************************************************************** | -| File: Ap4BitStream.h +| AP4 - Bitstream Utility | -| AP4 - Bit Streams +| Copyright 2002-2008 Axiomatic Systems, LLC | -| (c) 2005 Gilles Boccon-Gibod -| Author: Gilles Boccon-Gibod (bok@bok.net) | - ****************************************************************/ +| 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_BIT_STREAM_H_ #define _AP4_BIT_STREAM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Types.h" #include "Ap4Results.h" /*---------------------------------------------------------------------- -| constants +| constants +---------------------------------------------------------------------*/ -#define AP4_ERROR_BASE_BITSTREAM -10000 +const int AP4_ERROR_BASE_BITSTREAM = -10000; -/* the max frame size we can handle */ -#define AP4_BITSTREAM_BUFFER_SIZE 8192 +// the max frame size we can handle +const unsigned int AP4_BITSTREAM_BUFFER_SIZE = 8192; -/* flags */ +// flags #define AP4_BITSTREAM_FLAG_EOS 0x01 -/* error codes */ -#define AP4_ERROR_NOT_ENOUGH_DATA (AP4_ERROR_BASE_BITSTREAM - 0) -#define AP4_ERROR_CORRUPTED_BITSTREAM (AP4_ERROR_BASE_BITSTREAM - 1) -#define AP4_ERROR_NOT_ENOUGH_FREE_BUFFER (AP4_ERROR_BASE_BITSTREAM - 2) +// error codes +const int AP4_ERROR_CORRUPTED_BITSTREAM = (AP4_ERROR_BASE_BITSTREAM - 0); +const int AP4_ERROR_NOT_ENOUGH_FREE_BUFFER = (AP4_ERROR_BASE_BITSTREAM - 1); /*---------------------------------------------------------------------- -| types helpers +| types helpers +---------------------------------------------------------------------*/ /* use long by default */ typedef unsigned int AP4_BitsWord; @@ -43,7 +59,7 @@ typedef unsigned int AP4_BitsWord; #define AP4_WORD_BYTES 4 /*---------------------------------------------------------------------- -| types +| types +---------------------------------------------------------------------*/ class AP4_BitStream { @@ -86,7 +102,7 @@ private: }; /*---------------------------------------------------------------------- -| macros +| macros +---------------------------------------------------------------------*/ #define AP4_BIT_MASK(_n) ((1<<(_n))-1) @@ -100,7 +116,7 @@ private: ((pointer) = AP4_BITSTREAM_POINTER_OFFSET(pointer, offset)) /*---------------------------------------------------------------------- -| AP4_BitStream::ReadCache +| AP4_BitStream::ReadCache +---------------------------------------------------------------------*/ inline AP4_BitsWord AP4_BitStream::ReadCache() const @@ -130,7 +146,7 @@ AP4_BitStream::ReadCache() const } /*---------------------------------------------------------------------- -| AP4_BitStream::ReadBits +| AP4_BitStream::ReadBits +---------------------------------------------------------------------*/ inline AP4_UI32 AP4_BitStream::ReadBits(unsigned int n) @@ -164,7 +180,7 @@ AP4_BitStream::ReadBits(unsigned int n) } /*---------------------------------------------------------------------- -| AP4_BitStream::ReadBit +| AP4_BitStream::ReadBit +---------------------------------------------------------------------*/ inline int AP4_BitStream::ReadBit() @@ -188,7 +204,7 @@ AP4_BitStream::ReadBit() } /*---------------------------------------------------------------------- -| AP4_BitStream::PeekBits +| AP4_BitStream::PeekBits +---------------------------------------------------------------------*/ inline AP4_UI32 AP4_BitStream::PeekBits(unsigned int n) @@ -208,7 +224,7 @@ AP4_BitStream::PeekBits(unsigned int n) } /*---------------------------------------------------------------------- -| AP4_BitStream::PeekBit +| AP4_BitStream::PeekBit +---------------------------------------------------------------------*/ inline int AP4_BitStream::PeekBit() @@ -227,7 +243,7 @@ AP4_BitStream::PeekBit() } /*---------------------------------------------------------------------- -| AP4_BitStream::SkipBits +| AP4_BitStream::SkipBits +---------------------------------------------------------------------*/ inline void AP4_BitStream::SkipBits(unsigned int n) @@ -252,7 +268,7 @@ AP4_BitStream::SkipBits(unsigned int n) } /*---------------------------------------------------------------------- -| AP4_BitStream::SkipBit +| AP4_BitStream::SkipBit +---------------------------------------------------------------------*/ inline void AP4_BitStream::SkipBit() @@ -267,7 +283,7 @@ AP4_BitStream::SkipBit() } /*---------------------------------------------------------------------- -| AP4_BitStream::ReadByte +| AP4_BitStream::ReadByte +---------------------------------------------------------------------*/ inline AP4_UI08 AP4_BitStream::ReadByte() @@ -277,7 +293,7 @@ AP4_BitStream::ReadByte() } /*---------------------------------------------------------------------- -| AP4_BitStream::PeekByte +| AP4_BitStream::PeekByte +---------------------------------------------------------------------*/ inline AP4_UI08 AP4_BitStream::PeekByte() diff --git a/src/filters/parser/mp4splitter/AP4/Source/Config/Ap4Config.h b/src/filters/parser/mp4splitter/AP4/Source/Config/Ap4Config.h index 6785185d3..da09a8b15 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Config/Ap4Config.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Config/Ap4Config.h @@ -1,72 +1,140 @@ -/*****************************************************************
-|
-| AP4 - Target Platform and Compiler Configuration
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_CONFIG_H_
-#define _AP4_CONFIG_H_
-
-/*----------------------------------------------------------------------
-| defaults
-+---------------------------------------------------------------------*/
-#define AP4_CONFIG_HAVE_CPP_STRING_H
-#define AP4_CONFIG_HAVE_STDIO_H
-#define AP4_CONFIG_HAVE_ASSERT_H
-
-#define AP4_CONFIG_HAVE_CPP_STRING
-
-#define AP4_CONFIG_HAVE_SNPRINTF
-
-/*----------------------------------------------------------------------
-| byte order
-+---------------------------------------------------------------------*/
-// define AP4_PLATFORM_BYTE_ORDER to one of these two choices
-#define AP4_PLATFORM_BYTE_ORDER_BIG_ENDIAN 0
-#define AP4_PLATFORM_BYTE_ORDER_LITTLE_ENDIAN 1
-
-#ifdef __ppc__
-#define AP4_PLATFORM_BYTE_ORDER AP4_PLATFORM_BYTE_ORDER_BIG_ENDIAN
-#endif
-
-#define AP4_PLATFORM_BYTE_ORDER AP4_PLATFORM_BYTE_ORDER_LITTLE_ENDIAN
-
-/*----------------------------------------------------------------------
-| Win32 specifics
-+---------------------------------------------------------------------*/
-#if defined(WIN32) || defined(_WIN64)
-#define snprintf _snprintf
-#if _MSC_VER < 1500
-#define vsnprintf _vsnprintf
-#endif
-#if defined(_DEBUG)
-#define AP4_DEBUG
-#endif
-#endif
-#include "../../../../../../DSUtil/SharedInclude.h"
-#include <Afx.h>
-#endif // _AP4_CONFIG_H_
+/***************************************************************** +| +| AP4 - Target Platform and Compiler Configuration +| +| 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 Platform Configuration + */ +#ifndef _AP4_CONFIG_H_ +#define _AP4_CONFIG_H_ + +/*---------------------------------------------------------------------- +| defaults ++---------------------------------------------------------------------*/ +#define AP4_CONFIG_HAVE_STDIO_H +#define AP4_CONFIG_HAVE_ASSERT_H +#define AP4_CONFIG_HAVE_STRING_H +#define AP4_CONFIG_HAVE_SNPRINTF +#define AP4_CONFIG_HAVE_VSNPRINTF +#define AP4_CONFIG_HAVE_INT64 + +/*---------------------------------------------------------------------- +| byte order ++---------------------------------------------------------------------*/ +// define AP4_PLATFORM_BYTE_ORDER to one of these two choices +#define AP4_PLATFORM_BYTE_ORDER_BIG_ENDIAN 0 +#define AP4_PLATFORM_BYTE_ORDER_LITTLE_ENDIAN 1 + +#if !defined(AP4_PLATFORM_BYTE_ORDER) +#if defined(__ppc__) +#define AP4_PLATFORM_BYTE_ORDER AP4_PLATFORM_BYTE_ORDER_BIG_ENDIAN +#else +#define AP4_PLATFORM_BYTE_ORDER AP4_PLATFORM_BYTE_ORDER_LITTLE_ENDIAN +#endif +#endif + +/*---------------------------------------------------------------------- +| standard C++ runtime ++---------------------------------------------------------------------*/ +#define APT_CONFIG_HAVE_NEW_H + +/*---------------------------------------------------------------------- +| platform specifics ++---------------------------------------------------------------------*/ + +/* Microsoft Platforms */ +#if defined(_MSC_VER) +#define AP4_CONFIG_INT64_TYPE __int64 +#if (_MSC_VER >= 1400) && !defined(_WIN32_WCE) +#define AP4_CONFIG_HAVE_FOPEN_S +#define AP4_snprintf(s,c,f,...) _snprintf_s(s,c,_TRUNCATE,f,__VA_ARGS__) +#define AP4_vsnprintf(s,c,f,a) _vsnprintf_s(s,c,_TRUNCATE,f,a) +#define fileno _fileno +#define AP4_fseek _fseeki64 +#define AP4_ftell _ftelli64 +#else +#define AP4_snprintf _snprintf +#define AP4_vsnprintf _vsnprintf +#endif +#if defined(_WIN32_WCE) +#define AP4_fseek fseek +#define AP4_ftell ftell +#endif +#if defined(_DEBUG) +#define _CRTDBG_MAP_ALLOC +#endif +#endif + +/* Cygwin */ +#if defined(__CYGWIN__) +#define AP4_fseek fseek +#define AP4_ftell ftell +#endif + +/* Symbian */ +#if defined(__SYMBIAN32__) +#undef APT_CONFIG_HAVE_NEW_H +#include "e32std.h" +/** + * Define the Platform byte order here + * for Symbian. + */ +#define AP4_PLATFORM_BYTE_ORDER AP4_PLATFORM_BYTE_ORDER_LITTLE_ENDIAN +#define AP4_fseek fseek +#define AP4_ftell ftell +#define explicit +#endif + +/* Android */ +#if defined(ANDROID) +#define AP4_CONFIG_NO_RTTI +#define AP4_CONFIG_NO_EXCEPTIONS +#endif + +/*---------------------------------------------------------------------- +| defaults ++---------------------------------------------------------------------*/ +#if !defined(AP4_CONFIG_INT64_TYPE) +#define AP4_CONFIG_INT64_TYPE long long +#endif + +#if !defined(AP4_fseek) +#define AP4_fseek fseeko +#endif +#if !defined(AP4_ftell) +#define AP4_ftell ftello +#endif + +/* some compilers (ex: MSVC 8) deprecate those, so we rename them */ +#if !defined(AP4_snprintf) +#define AP4_snprintf snprintf +#endif +#if !defined(AP4_vsnprintf) +#define AP4_vsnprintf vsnprintf +#endif + +#endif // _AP4_CONFIG_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4.h index 578438370..1d75ed77d 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4.h @@ -2,7 +2,7 @@ | | AP4 - Main Header | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -25,18 +25,264 @@ | 02111-1307, USA. | ****************************************************************/ +/** +* @file +* @brief Top Level include file +* +* Applications should only need to include that file, as it will +* include all the more specific include files required to use the API +*/ + +/** @mainpage Bento4 SDK +* +* @section intro_sec Introduction +* Bento4/AP4 is a C++ class library designed to read and write ISO-MP4 files. +* This format is defined in ISO/IEC 14496-12, 14496-14 and 14496-15. +* The format is a derivative of the Apple Quicktime file format. +* Because of that, Bento4 can be used to read and write a number of Quicktime files +* as well, even though some Quicktime specific features are not supported. +* In addition, Bento4 supports a number of extensions as defined in various +* other specifications. This includes some support for ISMA Encrytion and +* Decryption as defined in the ISMA E&A specification (http://www.isma.tv), +* OMA 2.0 PDCF Encryption and Decryption as defined in the OMA 2.0 PDCF +* specification (http://www.openmobilealliance.org) and iTunes compatible +* metadata. +* The SDK includes a number of command line tools, built using the class library, +* that serve as general purpose tools as well as examples of how to use the API. +* +* The SDK is designed to be cross-platform. The code is very portable; it can +* be compiled with any sufficiently modern C++ compiler. The code does not rely +* on any external library; all the code necessary to compile the SDK and its +* tools is included in the standard distribution. The standard distribution +* contains makefiles for unix-like operating systems, including Linux, project +* files for Microsoft Visual Studio, and an XCode project for MacOS X. There is +* also support for building the library with the SCons build system. +* +* @section building Building the SDK +* Building the SDK will produce a C++ class library and some command line tools. +* For the makefile-based configurations, 'make sdk' will produce an SDK +* directory layout with a bin/ lib/ and include/ subdirectories containing +* respectively the binaries, library and header files. +* +* @subsection build_win32 Windows +* Open the solution file Build/Targets/Build/Targets/x86-microsoft-win32-vs2005 +* Building the solution will build the class library and command line tools. +* The script Build/Targets/Build/Targets/x86-microsoft-win32-vs2005/make-sdk.sh +* will create the SDK directory structure as described above. +* +* @subsection build_linux Linux +* Go to Build/Targets/x86-unknown-linux or Build/Targets/<target-name> +* for any linux-based target, and use the 'make' +* command to build the library and tools, or 'make sdk' to build the SDK +* directory structure. +* +* @subsection build_cygwin Cygwin +* Go to Build/Targets/x86-unknown-cygwin and follow the same instructions as +* for the Linux platform. +* +* @subsection build_macos MacOS +* Use the XCode project file located under Build/Targets/ppc-apple-macosx +* +* @subsection build_scons Using SCons +* There is experimental support for building the SDK using the python-based +* SCons tool (http://www.scons.org). The top level configuration is located +* at the root of the SDK, and will output all the object files and binaries +* to a sub-directory under Build/SCons/Targets/<target-name>/<config-name>. +* +* @subsection build_others Other Platforms +* Other plaftorms can be built by adapting the makefiles for the generic +* gcc-based configurations. +* +* @section mp4_structure Structure of an MP4 file +* +* An MP4 file consists of a tree of atoms (also known as boxes). The atoms +* contain the information about the different media tracks for the file, as +* well as other information, such as metadata. +* The Bento4 class library parses files an constructs an in-memory representation +* of the atoms, and provides an API that is an abstraction layer for the +* way the information is actually encoded in those atoms. +* +* @section reading Reading Files +* +* The class #AP4_File represents all the information about an MP4 file. +* Internally, a tree of #AP4_Atom objects plus other helper objects holds +* the actual information. +* To create an instance of the class, the caller must pass a reference to +* an #AP4_ByteStream object that represents the file data storage. The SDK +* includes two subclasses of the abstract #AP4_ByteStream class: +* #AP4_FileByteStream for reading/writing disk-based files and +* #AP4_MemoryByteStream for working with in-memory file images. +* Once you have created an #AP4_File object, you can get to the media data by +* accessing the #AP4_Track objects of its #AP4_Movie (see #AP4_File::GetMovie). +* The #AP4_Track exposes the necessary methods for you to get the +* #AP4_SampleDescription (typically to initialize your decoder) and to get the +* #AP4_Sample objects from the track. +* These #AP4_Sample objects give you the meta information you need (such as +* timestamps) as well as the sample data that they point to. +* You can also explore the entire tree of atoms by calling #AP4_File::Inspect, +* passing an instance of #AP4_AtomInspector. #AP4_AtomInspector is an abstract +* base class for a visitor of the tree of #AP4_Atom objects. The SDK includes +* an concrete subclass, #AP4_PrintInspector, can be used to print out a text +* representation of the atoms as they are visited. See the Mp4Dump command line +* application for an example. +* +* @section writing Writing Files +* +* To create a new MP4 file, you first create an #AP4_SyntheticSampleTable +* sample table for each track in your file. You specify the sample description +* for the media samples in each track by calling #AP4_SyntheticSampleTable::AddSampleDescription +* with the description for the samples of that track. Samples can then be added +* to the sample table with the #AP4_SyntheticSampleTable::AddSample method. +* Once all the samples of all the tracks have been added to the sample tables, +* you can create an #AP4_Movie, and an #AP4_Track from each sample table, add the track +* to the movie, and finally create an #AP4_File from the movie object. +* Finally, the #AP4_File object can be serialized to a byte stream (such as an +* #AP4_FileByteStream) using the #AP4_FileWriter class. +* See the Aac2Mp4 application for an example. +* +* @section tracks Tracks +* +* The #AP4_Movie object of an #AP4_File has a list of #AP4_Track objects. Each +* #AP4_Track represents a media track in the file. From this object, you can +* obtain the type, duration, etc.. of the tracks. This object also provides +* access to the media samples in the track. Tracks are made up of media samples, +* stored in an 'mdat' atom (media data) and a sample table that provides all the +* information about the individual samples, such as size, timestamps, sample +* description, etc... Media samples are represented by #AP4_Sample objects. +* You can obtain a track's samples by calling the #AP4_Track::GetSample method. +* You can also directly read the payload of a media sample by calling the +* #AP4_Track::ReadSample method if you want to bypass the intermediate step of +* going through an #AP4_Sample object. +* The information about the samples in a track is represented by subclasses of +* the #AP4_SampleDescription class. The sample descriptions contain information +* about media-specific parameters, such as video resolution, audio sampling rates +* and others. +* See the Mp4Info and Mp42Aac command line applications as examples. +* +* @section advanced Advanced Topics +* +* @subsection factory Custom Atoms +* +* The SDK has built-in support for most of the standard atom types as defined +* in the spec. But an application may want to extend the library to support +* non-standard atom type, such as custom atoms whose definition is proprietary. +* The base class for all atoms is #AP4_Atom. Instances of subclasses of this class +* are created by the #AP4_AtomFactory object. The factory knows about all the +* #AP4_Atom subclasses included in the SDK, and maintains a list of +* #AP4_AtomFactory::TypeHandler type handlers. When the factory encounters an atom +* that is not one of the built-in atom type, it calls all the registered type +* handlers, in turn, until one of them accept to handle the type and create the +* corresponding atom. The custom atoms must be implemented as subclasses of +* #AP4_Atom and override at least the #AP4_Atom::WriteFields method. The custom +* atoms should also override #AP4_Atom::InspectFields if they want to provide +* meaningful information when inspected. +* +* @subsection tranformations Transformations +* The SDK provides support for transforming MP4 files. Transformations are useful +* to perform tasks such as editing (removing or adding atoms) and encryption or +* decryption. When the atom tree for the file changes, the entire file needs to +* change, because in most cases, the size of the 'moov' atom will change, and +* thus change the offset of the media samples in the 'mdat' atom. +* To facilitate this operation, the class #AP4_Processor provides the base +* functionality for managing all the updates to the sample tables. Subclasses +* of the #AP4_Processor class can override certain methods to carry out specific +* changes to the structure of the atom tree and/or the media samples. #AP4_Processor +* defines an abstract base class, #AP4_Processor::TrackHandler that defines the +* interface that specific track modification classes must implement. A subclass +* of #AP4_Processor may create such an #AP4_Processor::TrackHandler subclass instance +* when is #AP4_Processor::CreateTrackHandler is called for one of the tracks in the +* file. +* See the sample applications Mp4Edit, Mp4Encrpt and Mp4Decrypt as examples. +* +* @subsection encryption Encryption and Decryption +* +* The SDK has support for encrypting and decrypting tracks as specified by the +* ISMA Encryption and Authentication specification as well as OMA 2.0 PDCF. +* The supporting classes found in Ap4IsmaCryp.h and AP4_OmaDcf.h provide a subclass +* of #AP4_Processor for encrypting or decrypting entire files. +* The class #AP4_IsmaCipher and #AP4_OmaDcfSampleDecrypter implement the generic +* #AP4_SampleDecrypter interface that provides support for decrypting individual samples. +* The parameters necessary to instantiate an #AP4_IsmaCipher or an #AP4_OmaDcfSampleDecrypter +* can be retrieved from an encrypted track by accessing the track's sample descriptions, +* which are instances of the #AP4_ProtectedSampleDescription class. +* +* @subsection RTP Packets +* +* For files that contain hint tracks, the SDK provides support for generating +* RTP packets that can be used to stream the media using the RTP and RTSP protocols. +* See the application Mp4RtpHintInfo for an example of how to generate the create +* RTP packets from a file and generate the SDP information for the RTSP protocol. +*/ #ifndef _AP4_H_ #define _AP4_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "../../../StdAfx.h" #include "Ap4Config.h" +#include "Ap4Version.h" #include "Ap4Types.h" #include "Ap4Constants.h" #include "Ap4Results.h" #include "Ap4Debug.h" +#include "Ap4Utils.h" +#include "Ap4DynamicCast.h" +#include "Ap4FileByteStream.h" +#include "Ap4Movie.h" +#include "Ap4Track.h" +#include "Ap4File.h" +#include "Ap4FileWriter.h" +#include "Ap4FileCopier.h" +#include "Ap4HintTrackReader.h" +#include "Ap4Processor.h" +#include "Ap4MetaData.h" +#include "Ap4AtomFactory.h" +#include "Ap4SampleEntry.h" +#include "Ap4Sample.h" +#include "Ap4DataBuffer.h" +#include "Ap4SampleTable.h" +#include "Ap4SyntheticSampleTable.h" +#include "Ap4AtomSampleTable.h" +#include "Ap4UrlAtom.h" +#include "Ap4MoovAtom.h" +#include "Ap4MvhdAtom.h" +#include "Ap4TrakAtom.h" +#include "Ap4HdlrAtom.h" +#include "Ap4DrefAtom.h" +#include "Ap4TkhdAtom.h" +#include "Ap4MdhdAtom.h" +#include "Ap4StsdAtom.h" +#include "Ap4StscAtom.h" +#include "Ap4StcoAtom.h" +#include "Ap4StszAtom.h" +#include "Ap4EsdsAtom.h" +#include "Ap4SttsAtom.h" +#include "Ap4CttsAtom.h" +#include "Ap4StssAtom.h" +#include "Ap4FtypAtom.h" +#include "Ap4VmhdAtom.h" +#include "Ap4SmhdAtom.h" +#include "Ap4NmhdAtom.h" +#include "Ap4HmhdAtom.h" +#include "Ap4SchmAtom.h" +#include "Ap4FrmaAtom.h" +#include "Ap4TimsAtom.h" +#include "Ap4RtpAtom.h" +#include "Ap4SdpAtom.h" +#include "Ap4IkmsAtom.h" +#include "Ap4IsfmAtom.h" +#include "Ap4IsltAtom.h" +#include "Ap4TrefTypeAtom.h" +#include "Ap4OmaDcf.h" +#include "Ap4IsmaCryp.h" +#include "Ap4OdafAtom.h" +#include "Ap4OhdrAtom.h" +#include "Ap4OdheAtom.h" +#include "Ap4OddaAtom.h" +#include "Ap4AvccAtom.h" +#include "Ap4Marlin.h" +#include "Ap4GrpiAtom.h" +#include "Ap48bdlAtom.h" #endif // _AP4_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap48bdlAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap48bdlAtom.h new file mode 100644 index 000000000..3c3cadd2e --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap48bdlAtom.h @@ -0,0 +1,81 @@ +/***************************************************************** +| +| 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. +| + ****************************************************************/ + + #ifndef _AP4_8BDL_ATOM_H_ + #define _AP4_8BDL_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4DataBuffer.h" +#include "Ap4Atom.h" +#include "Ap4DynamicCast.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_8BDL_XML_DATA_ENCODING = AP4_ATOM_TYPE('x','m','l',' '); + +/*---------------------------------------------------------------------- +| AP4_8bdlAtom ++---------------------------------------------------------------------*/ +class AP4_8bdlAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_8bdlAtom, AP4_Atom) + + // virtual constructor + static AP4_8bdlAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // constructors + AP4_8bdlAtom(AP4_UI32 encoding, + AP4_UI32 encoding_version, + const AP4_Byte* data, + AP4_Size data_size); + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // accessors + AP4_UI32 GetEncoding() { return m_Encoding; } + AP4_UI32 GetEncodingVersion() { return m_EncodingVersion; } + const AP4_DataBuffer& GetBundleData() { return m_BundleData; } + +private: + // methods + AP4_8bdlAtom(AP4_Size size, + AP4_ByteStream& stream); + + // members + AP4_UI32 m_Encoding; + AP4_UI32 m_EncodingVersion; + AP4_DataBuffer m_BundleData; +}; + +#endif // _AP4_8BDL_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Array.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Array.h index 2a5d4e43e..d8b08c397 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Array.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Array.h @@ -2,7 +2,7 @@ | | AP4 - Arrays | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -25,113 +25,176 @@ | 02111-1307, USA. | ****************************************************************/ +/** + * @file + * @brief Arrays + */ #ifndef _AP4_ARRAY_H_ #define _AP4_ARRAY_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ +#include "Ap4Config.h" +#if defined(APT_CONFIG_HAVE_NEW_H) +#include <new> +#endif #include "Ap4Types.h" #include "Ap4Results.h" /*---------------------------------------------------------------------- -| constants +| constants +---------------------------------------------------------------------*/ const int AP4_ARRAY_INITIAL_COUNT = 64; /*---------------------------------------------------------------------- -| AP4_Array +| AP4_Array +---------------------------------------------------------------------*/ template <typename T> class AP4_Array { public: // methods - AP4_Array<T>(): m_AllocatedCount(0), m_ItemCount(0), m_Items(0) {} - virtual ~AP4_Array<T>(); - AP4_Cardinal ItemCount() { return m_ItemCount; } + AP4_Array(): m_AllocatedCount(0), m_ItemCount(0), m_Items(0) {} + AP4_Array(const T* items, AP4_Size count); + virtual ~AP4_Array(); + AP4_Cardinal ItemCount() const { return m_ItemCount; } AP4_Result Append(const T& item); - T& operator[](unsigned long idx); + AP4_Result RemoveLast(); + T& operator[](unsigned long idx) { return m_Items[idx]; } + const T& operator[](unsigned long idx) const { return m_Items[idx]; } + AP4_Result Clear(); AP4_Result EnsureCapacity(AP4_Cardinal count); + AP4_Result SetItemCount(AP4_Cardinal item_count); protected: // members AP4_Cardinal m_AllocatedCount; AP4_Cardinal m_ItemCount; T* m_Items; - T m_OverflowItem; }; /*---------------------------------------------------------------------- -| AP4_Array<T>::~AP4_Array<T> +| AP4_Array<T>::AP4_Array<T> +---------------------------------------------------------------------*/ template <typename T> -AP4_Array<T>::~AP4_Array<T>() +AP4_Array<T>::AP4_Array(const T* items, AP4_Size count) : + m_AllocatedCount(count), + m_ItemCount(count), + m_Items((T*)::operator new(count*sizeof(T))) { - delete[] m_Items; + for (unsigned int i=0; i<count; i++) { + new ((void*)&m_Items[i]) T(items[i]); + } } /*---------------------------------------------------------------------- -| AP4_Array<T>::EnsureCapacity +| AP4_Array<T>::~AP4_Array<T> ++---------------------------------------------------------------------*/ +template <typename T> +AP4_Array<T>::~AP4_Array() +{ + Clear(); + ::operator delete((void*)m_Items); +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Clear ++---------------------------------------------------------------------*/ +template <typename T> +AP4_Result +AP4_Array<T>::Clear() +{ + // destroy all items + for (AP4_Ordinal i=0; i<m_ItemCount; i++) { + m_Items[i].~T(); + } + + m_ItemCount = 0; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Array<T>::EnsureCapacity +---------------------------------------------------------------------*/ template <typename T> AP4_Result AP4_Array<T>::EnsureCapacity(AP4_Cardinal count) { + // check if we already have enough if (count <= m_AllocatedCount) return AP4_SUCCESS; - unsigned long new_count; - if (m_AllocatedCount) { - new_count = 2*m_AllocatedCount; - } else { - new_count = AP4_ARRAY_INITIAL_COUNT; - } - // (re)allocate the items - T* new_items = DNew T[new_count]; + T* new_items = (T*) ::operator new (count*sizeof(T)); if (new_items == NULL) { return AP4_ERROR_OUT_OF_MEMORY; } if (m_ItemCount && m_Items) { for (unsigned int i=0; i<m_ItemCount; i++) { - new_items[i] = m_Items[i]; + new ((void*)&new_items[i]) T(m_Items[i]); + m_Items[i].~T(); } - delete[] m_Items; + ::operator delete((void*)m_Items); } m_Items = new_items; - m_AllocatedCount = new_count; + m_AllocatedCount = count; return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_Array<T>::operator[] +| AP4_Array<T>::SetItemCount ++---------------------------------------------------------------------*/ +template <typename T> +AP4_Result +AP4_Array<T>::SetItemCount(AP4_Cardinal item_count) +{ + AP4_Result result = EnsureCapacity(item_count); + if (AP4_FAILED(result)) return result; + m_ItemCount = item_count; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Array<T>::RemoveLast +---------------------------------------------------------------------*/ template <typename T> -T& -AP4_Array<T>::operator[](unsigned long idx) +AP4_Result +AP4_Array<T>::RemoveLast() { - if (idx >= m_ItemCount) { - return m_OverflowItem; + if (m_ItemCount) { + m_Items[--m_ItemCount].~T(); + return AP4_SUCCESS; } else { - return m_Items[idx]; + return AP4_ERROR_OUT_OF_RANGE; } } /*---------------------------------------------------------------------- -| AP4_Array<T>::Append +| AP4_Array<T>::Append +---------------------------------------------------------------------*/ template <typename T> AP4_Result AP4_Array<T>::Append(const T& item) { - // ensure capacity - AP4_Result result = EnsureCapacity(m_ItemCount+1); - if (result != AP4_SUCCESS) return result; + // ensure that we have enough space + if (m_AllocatedCount < m_ItemCount+1) { + // try double the size, with a minimum + unsigned long new_count = m_AllocatedCount?2*m_AllocatedCount:AP4_ARRAY_INITIAL_COUNT; + + // if that's still not enough, just ask for what we need + if (new_count < m_ItemCount+1) new_count = m_ItemCount+1; + + // reserve the space + AP4_Result result = EnsureCapacity(new_count); + if (result != AP4_SUCCESS) return result; + } // store the item - m_Items[m_ItemCount++] = item; + new ((void*)&m_Items[m_ItemCount++]) T(item); return AP4_SUCCESS; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Atom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Atom.cpp index 57ca254d9..a0aecfbe7 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Atom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Atom.cpp @@ -2,7 +2,7 @@ | | AP4 - Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,23 +27,45 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" +#include "Ap4Types.h" #include "Ap4Atom.h" #include "Ap4Utils.h" #include "Ap4ContainerAtom.h" -#include "Ap4StsdAtom.h" +#include "Ap4AtomFactory.h" #include "Ap4Debug.h" +static const unsigned int AP4_ATOM_MAX_CLONE_SIZE = 1048576; // 1 meg + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_Atom) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_AtomParent) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_NullTerminatedStringAtom) + +/*---------------------------------------------------------------------- +| AP4_Atom::TypeFromString ++---------------------------------------------------------------------*/ +AP4_Atom::Type +AP4_Atom::TypeFromString(const char* s) +{ + // convert the name into an atom type + return ((AP4_UI32)s[0])<<24 | + ((AP4_UI32)s[1])<<16 | + ((AP4_UI32)s[2])<< 8 | + ((AP4_UI32)s[3]); +} + /*---------------------------------------------------------------------- -| AP4_Atom::AP4_Atom +| AP4_Atom::AP4_Atom +---------------------------------------------------------------------*/ -AP4_Atom::AP4_Atom(Type type, - bool is_full) : +AP4_Atom::AP4_Atom(Type type, AP4_UI32 size /* = AP4_ATOM_HEADER_SIZE */) : m_Type(type), - m_Size(is_full ? AP4_FULL_ATOM_HEADER_SIZE : AP4_ATOM_HEADER_SIZE), - m_IsFull(is_full), + m_Size32(size), + m_Size64(0), + m_IsFull(false), m_Version(0), m_Flags(0), m_Parent(NULL) @@ -51,55 +73,105 @@ AP4_Atom::AP4_Atom(Type type, } /*---------------------------------------------------------------------- -| AP4_Atom::AP4_Atom +| AP4_Atom::AP4_Atom +---------------------------------------------------------------------*/ -AP4_Atom::AP4_Atom(Type type, - AP4_Size size, - bool is_full) : +AP4_Atom::AP4_Atom(Type type, AP4_UI64 size, bool force_64) : m_Type(type), - m_Size(size), - m_IsFull(is_full), + m_Size32(0), + m_Size64(0), + m_IsFull(false), m_Version(0), m_Flags(0), m_Parent(NULL) { + SetSize(size, force_64); } /*---------------------------------------------------------------------- -| AP4_Atom::AP4_Atom +| AP4_Atom::AP4_Atom +---------------------------------------------------------------------*/ -AP4_Atom::AP4_Atom(Type type, - AP4_Size size, - bool is_full, - AP4_ByteStream& stream) : +AP4_Atom::AP4_Atom(Type type, + AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags) : + m_Type(type), + m_Size32(size), + m_Size64(0), + m_IsFull(true), + m_Version(version), + m_Flags(flags), + m_Parent(NULL) +{ +} + +/*---------------------------------------------------------------------- +| AP4_Atom::AP4_Atom ++---------------------------------------------------------------------*/ +AP4_Atom::AP4_Atom(Type type, + AP4_UI64 size, + bool force_64, + AP4_UI32 version, + AP4_UI32 flags) : m_Type(type), - m_Size(size), - m_IsFull(is_full), + m_Size32(0), + m_Size64(0), + m_IsFull(true), + m_Version(version), + m_Flags(flags), m_Parent(NULL) { - // if this is a full atom, read the version and flags - if (is_full) { - AP4_UI32 header; - stream.ReadUI32(header); - m_Version = (header>>24)&0xFF; - m_Flags = (header&0xFFFFFF); + SetSize(size, force_64); +} + +/*---------------------------------------------------------------------- +| AP4_Atom::ReadFullHeader ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Atom::ReadFullHeader(AP4_ByteStream& stream, + AP4_UI32& version, + AP4_UI32& flags) +{ + AP4_UI32 header; + AP4_CHECK(stream.ReadUI32(header)); + version = (header>>24)&0x000000FF; + flags = (header )&0x00FFFFFF; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Atom::SetSize ++---------------------------------------------------------------------*/ +void +AP4_Atom::SetSize(AP4_UI64 size, bool force_64) +{ + if (!force_64) { + // see if we need to implicitely force 64-bit encoding + if (m_Size32 == 1 && m_Size64 <= 0xFFFFFFFF) { + // we have a forced 64-bit encoding + force_64 = true; + } + } + if ((size >> 32) == 0 && !force_64) { + m_Size32 = (AP4_UI32)size; + m_Size64 = 0; } else { - m_Version = 0; - m_Flags = 0; + m_Size32 = 1; + m_Size64 = size; } } /*---------------------------------------------------------------------- -| AP4_Atom::GetHeaderSize +| AP4_Atom::GetHeaderSize +---------------------------------------------------------------------*/ AP4_Size -AP4_Atom::GetHeaderSize() +AP4_Atom::GetHeaderSize() const { - return m_IsFull ? AP4_FULL_ATOM_HEADER_SIZE : AP4_ATOM_HEADER_SIZE; + return (m_IsFull ? AP4_FULL_ATOM_HEADER_SIZE : AP4_ATOM_HEADER_SIZE)+(m_Size32==1?8:0); } /*---------------------------------------------------------------------- -| AP4_Atom::WriteHeader +| AP4_Atom::WriteHeader +---------------------------------------------------------------------*/ AP4_Result AP4_Atom::WriteHeader(AP4_ByteStream& stream) @@ -107,13 +179,19 @@ AP4_Atom::WriteHeader(AP4_ByteStream& stream) AP4_Result result; // write the size - result = stream.WriteUI32(m_Size); + result = stream.WriteUI32(m_Size32); if (AP4_FAILED(result)) return result; // write the type result = stream.WriteUI32(m_Type); if (AP4_FAILED(result)) return result; + // handle 64-bit sizes + if (m_Size32 == 1) { + result = stream.WriteUI64(m_Size64); + if (AP4_FAILED(result)) return result; + } + // for full atoms, write version and flags if (m_IsFull) { result = stream.WriteUI08(m_Version); @@ -126,7 +204,7 @@ AP4_Atom::WriteHeader(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_Atom::Write +| AP4_Atom::Write +---------------------------------------------------------------------*/ AP4_Result AP4_Atom::Write(AP4_ByteStream& stream) @@ -134,7 +212,7 @@ AP4_Atom::Write(AP4_ByteStream& stream) AP4_Result result; #if defined(AP4_DEBUG) - AP4_Offset before; + AP4_Position before; stream.Tell(before); #endif @@ -147,16 +225,31 @@ AP4_Atom::Write(AP4_ByteStream& stream) if (AP4_FAILED(result)) return result; #if defined(AP4_DEBUG) - AP4_Offset after; + AP4_Position after; stream.Tell(after); - AP4_ASSERT(after-before == m_Size); + AP4_UI64 atom_size = GetSize(); + if (after-before != atom_size) { + AP4_Debug("ERROR: atom size mismatch (declared size=%d, actual size=%d)\n", + (AP4_UI32)atom_size, (AP4_UI32)(after-before)); + AP4_Atom* atom = this; + while (atom) { + char name[7]; + name[0] = '['; + AP4_FormatFourCharsPrintable(&name[1], atom->GetType()); + name[5] = ']'; + name[6] = '\0'; + AP4_Debug(" while writing %s\n", name); + atom = AP4_DYNAMIC_CAST(AP4_Atom, atom->GetParent()); + } + AP4_ASSERT(after-before == atom_size); + } #endif return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_Atom::Inspect +| AP4_Atom::Inspect +---------------------------------------------------------------------*/ AP4_Result AP4_Atom::Inspect(AP4_AtomInspector& inspector) @@ -169,7 +262,7 @@ AP4_Atom::Inspect(AP4_AtomInspector& inspector) } /*---------------------------------------------------------------------- -| AP4_Atom::InspectHeader +| AP4_Atom::InspectHeader +---------------------------------------------------------------------*/ AP4_Result AP4_Atom::InspectHeader(AP4_AtomInspector& inspector) @@ -177,19 +270,39 @@ AP4_Atom::InspectHeader(AP4_AtomInspector& inspector) // write atom name char name[7]; name[0] = '['; - AP4_FormatFourChars(&name[1], m_Type); + AP4_FormatFourCharsPrintable(&name[1], m_Type); name[5] = ']'; name[6] = '\0'; - char size[64]; - AP4_StringFormat(size, sizeof(size), "size=%ld+%ld", GetHeaderSize(), - m_Size-GetHeaderSize()); - inspector.StartElement(name, size); + char header[128]; + char extra[32] = ""; + if (m_IsFull) { + if (m_Version && m_Flags) { + AP4_FormatString(extra, sizeof(extra), + ", version=%d, flags=%x", + m_Version, + m_Flags); + } else if (m_Version) { + AP4_FormatString(extra, sizeof(extra), + ", version=%d", + m_Version); + } else if (m_Flags) { + AP4_FormatString(extra, sizeof(extra), + ", flags=%x", + m_Flags); + } + } + AP4_FormatString(header, sizeof(header), + "size=%ld+%lld%s", + GetHeaderSize(), + GetSize()-GetHeaderSize(), + extra); + inspector.StartElement(name, header); return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_Atom::Detach +| AP4_Atom::Detach +---------------------------------------------------------------------*/ AP4_Result AP4_Atom::Detach() @@ -202,24 +315,66 @@ AP4_Atom::Detach() } /*---------------------------------------------------------------------- -| AP4_UnknownAtom::AP4_UnknownAtom +| AP4_Atom::Clone ++---------------------------------------------------------------------*/ +AP4_Atom* +AP4_Atom::Clone() +{ + AP4_Atom* clone = NULL; + + // check the size (refuse to clone atoms that are too large) + AP4_LargeSize size = GetSize(); + if (size > AP4_ATOM_MAX_CLONE_SIZE) return NULL; + + // create a memory byte stream to which we can serialize + AP4_MemoryByteStream* mbs = new AP4_MemoryByteStream((AP4_Size)GetSize()); + + // serialize to memory + if (AP4_FAILED(Write(*mbs))) goto end; + + // create the clone for the serialized form + mbs->Seek(0); + AP4_DefaultAtomFactory::Instance.CreateAtomFromStream(*mbs, clone); + +end: + // release the memory stream + mbs->Release(); + + return clone; +} + +/*---------------------------------------------------------------------- +| AP4_UnknownAtom::AP4_UnknownAtom +---------------------------------------------------------------------*/ AP4_UnknownAtom::AP4_UnknownAtom(Type type, - AP4_Size size, - bool is_full, + AP4_UI64 size, AP4_ByteStream& stream) : - AP4_Atom(type, size, is_full, stream), + AP4_Atom(type, size), m_SourceStream(&stream) { - // store source stream offset - stream.Tell(m_SourceOffset); + // store source stream position + stream.Tell(m_SourcePosition); + + // clamp to the file size + AP4_UI64 file_size; + if (AP4_SUCCEEDED(stream.GetSize(file_size))) { + if (m_SourcePosition-GetHeaderSize()+size > file_size) { + if (m_Size32 == 1) { + // size is encoded as a large size + m_Size64 = file_size-m_SourcePosition; + } else { + AP4_ASSERT(size <= 0xFFFFFFFF); + m_Size32 = (AP4_UI32)(file_size-m_SourcePosition); + } + } + } // keep a reference to the source stream m_SourceStream->AddReference(); } /*---------------------------------------------------------------------- -| AP4_UnknownAtom::~AP4_UnknownAtom +| AP4_UnknownAtom::~AP4_UnknownAtom +---------------------------------------------------------------------*/ AP4_UnknownAtom::~AP4_UnknownAtom() { @@ -230,7 +385,7 @@ AP4_UnknownAtom::~AP4_UnknownAtom() } /*---------------------------------------------------------------------- -| AP4_UnknownAtom::WriteFields +| AP4_UnknownAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_UnknownAtom::WriteFields(AP4_ByteStream& stream) @@ -239,23 +394,103 @@ AP4_UnknownAtom::WriteFields(AP4_ByteStream& stream) // check that we have a source stream // and a normal size - if (m_SourceStream == NULL || m_Size < 8) { + if (m_SourceStream == NULL || GetSize() < 8) { 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_SourceOffset); + result = m_SourceStream->Seek(m_SourcePosition); if (AP4_FAILED(result)) return result; // copy the source stream to the output - result = m_SourceStream->CopyTo(stream, m_Size-GetHeaderSize()); + AP4_UI64 payload_size = GetSize()-GetHeaderSize(); + 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; } /*---------------------------------------------------------------------- -| AP4_AtomParent::~AP4_AtomParent +| AP4_UnknownAtom::Clone ++---------------------------------------------------------------------*/ +AP4_Atom* +AP4_UnknownAtom::Clone() +{ + // refuse to clone large atoms + if (GetSize() >= 32768) return NULL; + AP4_UI32 size = (AP4_UI32)GetSize(); + + AP4_MemoryByteStream* memory_stream = new AP4_MemoryByteStream(size); + m_SourceStream->Seek(m_SourcePosition); + m_SourceStream->CopyTo(*memory_stream, size); + memory_stream->Seek(0); + return new AP4_UnknownAtom(m_Type, GetSize(), *memory_stream); + memory_stream->Release(); +} + +/*---------------------------------------------------------------------- +| AP4_NullTerminatedStringAtom::AP4_NullTerminatedStringAtom ++---------------------------------------------------------------------*/ +AP4_NullTerminatedStringAtom::AP4_NullTerminatedStringAtom(AP4_Atom::Type type, const char* value) : + AP4_Atom(type, AP4_ATOM_HEADER_SIZE), + m_Value(value) +{ + m_Size32 += m_Value.GetLength()+1; +} + +/*---------------------------------------------------------------------- +| AP4_NullTerminatedStringAtom::AP4_NullTerminatedStringAtom ++---------------------------------------------------------------------*/ +AP4_NullTerminatedStringAtom::AP4_NullTerminatedStringAtom(AP4_Atom::Type type, + AP4_UI64 size, + AP4_ByteStream& stream) : + AP4_Atom(type, size) +{ + AP4_Size str_size = (AP4_Size)size-AP4_ATOM_HEADER_SIZE; + char* str = new char[str_size]; + stream.Read(str, str_size); + str[str_size-1] = '\0'; // force null-termination + m_Value = str; +} + +/*---------------------------------------------------------------------- +| AP4_NullTerminatedStringAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_NullTerminatedStringAtom::WriteFields(AP4_ByteStream& stream) +{ + if (m_Size32 > AP4_ATOM_HEADER_SIZE) { + AP4_Result result = stream.Write(m_Value.GetChars(), m_Value.GetLength()+1); + if (AP4_FAILED(result)) return result; + + // pad with zeros if necessary + AP4_Size padding = m_Size32-(AP4_ATOM_HEADER_SIZE+m_Value.GetLength()+1); + while (padding--) stream.WriteUI08(0); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_NullTerminatedStringAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_NullTerminatedStringAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("string value", m_Value.GetChars()); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_AtomParent::~AP4_AtomParent +---------------------------------------------------------------------*/ AP4_AtomParent::~AP4_AtomParent() { @@ -263,7 +498,7 @@ AP4_AtomParent::~AP4_AtomParent() } /*---------------------------------------------------------------------- -| AP4_AtomParent::AddChild +| AP4_AtomParent::AddChild +---------------------------------------------------------------------*/ AP4_Result AP4_AtomParent::AddChild(AP4_Atom* child, int position) @@ -304,7 +539,7 @@ AP4_AtomParent::AddChild(AP4_Atom* child, int position) } /*---------------------------------------------------------------------- -| AP4_AtomParent::RemoveChild +| AP4_AtomParent::RemoveChild +---------------------------------------------------------------------*/ AP4_Result AP4_AtomParent::RemoveChild(AP4_Atom* child) @@ -326,13 +561,13 @@ AP4_AtomParent::RemoveChild(AP4_Atom* child) } /*---------------------------------------------------------------------- -| AP4_AtomParent::DeleteChild +| AP4_AtomParent::DeleteChild +---------------------------------------------------------------------*/ AP4_Result -AP4_AtomParent::DeleteChild(AP4_Atom::Type type) +AP4_AtomParent::DeleteChild(AP4_Atom::Type type, AP4_Ordinal index /* = 0 */) { // find the child - AP4_Atom* child = GetChild(type); + AP4_Atom* child = GetChild(type, index); if (child == NULL) return AP4_FAILURE; // remove the child @@ -346,10 +581,10 @@ AP4_AtomParent::DeleteChild(AP4_Atom::Type type) } /*---------------------------------------------------------------------- -| AP4_AtomParent::GetChild +| AP4_AtomParent::GetChild +---------------------------------------------------------------------*/ AP4_Atom* -AP4_AtomParent::GetChild(AP4_Atom::Type type, AP4_Ordinal index /* = 0 */) +AP4_AtomParent::GetChild(AP4_Atom::Type type, AP4_Ordinal index /* = 0 */) const { AP4_Atom* atom; AP4_Result result = m_Children.Find(AP4_AtomFinder(type, index), atom); @@ -361,11 +596,12 @@ AP4_AtomParent::GetChild(AP4_Atom::Type type, AP4_Ordinal index /* = 0 */) } /*---------------------------------------------------------------------- -| AP4_AtomParent::FindChild +| AP4_AtomParent::FindChild +---------------------------------------------------------------------*/ AP4_Atom* AP4_AtomParent::FindChild(const char* path, - bool auto_create) + bool auto_create, + bool auto_create_full) { // start from here AP4_AtomParent* parent = this; @@ -406,13 +642,12 @@ AP4_AtomParent::FindChild(const char* path, if (atom == NULL) { // not found if (auto_create && (index == 0)) { - AP4_ContainerAtom* container = dynamic_cast<AP4_ContainerAtom*>(parent); - if (parent) { - atom = DNew AP4_ContainerAtom(type, false); - container->AddChild(atom); + if (auto_create_full) { + atom = new AP4_ContainerAtom(type, (AP4_UI32)0, (AP4_UI32)0); } else { - return NULL; + atom = new AP4_ContainerAtom(type); } + parent->AddChild(atom); } else { return NULL; } @@ -421,7 +656,7 @@ AP4_AtomParent::FindChild(const char* path, if (tail) { path = tail; // if this atom is an atom parent, recurse - parent = dynamic_cast<AP4_ContainerAtom*>(atom); + parent = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom); if (parent == NULL) return NULL; } else { return atom; @@ -431,3 +666,179 @@ AP4_AtomParent::FindChild(const char* path, // not found return NULL; } + +/*---------------------------------------------------------------------- +| AP4_AtomListWriter::Action ++---------------------------------------------------------------------*/ +const unsigned int AP4_ATOM_LIST_WRITER_MAX_PADDING=1024; + +AP4_Result +AP4_AtomListWriter::Action(AP4_Atom* atom) const +{ + AP4_Position before; + m_Stream.Tell(before); + + atom->Write(m_Stream); + + AP4_Position after; + m_Stream.Tell(after); + + AP4_UI64 bytes_written = after-before; + AP4_ASSERT(bytes_written <= atom->GetSize()); + if (bytes_written < atom->GetSize()) { + AP4_Debug("WARNING: atom serialized to fewer bytes than declared size\n"); + AP4_UI64 padding = atom->GetSize()-bytes_written; + if (padding > AP4_ATOM_LIST_WRITER_MAX_PADDING) { + AP4_Debug("WARNING: padding would be too large\n"); + return AP4_FAILURE; + } else { + for (unsigned int i=0; i<padding; i++) { + m_Stream.WriteUI08(0); + } + } + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MakePrefixString ++---------------------------------------------------------------------*/ +static void +AP4_MakePrefixString(unsigned int indent, char* prefix, AP4_Size size) +{ + if (size == 0) return; + if (indent >= size-1) indent = size-1; + for (unsigned int i=0; i<indent; i++) { + prefix[i] = ' '; + } + prefix[indent] = '\0'; +} + +/*---------------------------------------------------------------------- +| AP4_PrintInspector::AP4_PrintInspector ++---------------------------------------------------------------------*/ + AP4_PrintInspector::AP4_PrintInspector(AP4_ByteStream& stream, AP4_Cardinal indent) : + m_Stream(&stream), + m_Indent(indent) +{ + m_Stream->AddReference(); +} + +/*---------------------------------------------------------------------- +| AP4_PrintInspector::~AP4_PrintInspector ++---------------------------------------------------------------------*/ +AP4_PrintInspector::~AP4_PrintInspector() +{ + m_Stream->Release(); +} + +/*---------------------------------------------------------------------- +| AP4_PrintInspector::StartElement ++---------------------------------------------------------------------*/ +void +AP4_PrintInspector::StartElement(const char* name, const char* info) +{ + char prefix[256]; + AP4_MakePrefixString(m_Indent, prefix, sizeof(prefix)); + m_Stream->WriteString(prefix); + m_Stream->WriteString(name); + if (info) { + m_Stream->Write(" ", 1); + m_Stream->WriteString(info); + } + m_Stream->Write("\n", 1); + + m_Indent += 2; +} + +/*---------------------------------------------------------------------- +| AP4_PrintInspector::EndElement ++---------------------------------------------------------------------*/ +void +AP4_PrintInspector::EndElement() +{ + m_Indent -= 2; +} + +/*---------------------------------------------------------------------- +| AP4_PrintInspector::AddField ++---------------------------------------------------------------------*/ +void +AP4_PrintInspector::AddField(const char* name, const char* value, FormatHint) +{ + char prefix[256]; + AP4_MakePrefixString(m_Indent, prefix, sizeof(prefix)); + m_Stream->WriteString(prefix); + + m_Stream->WriteString(name); + m_Stream->WriteString(" = "); + m_Stream->WriteString(value); + m_Stream->Write("\n", 1); +} + +/*---------------------------------------------------------------------- +| AP4_PrintInspector::AddField ++---------------------------------------------------------------------*/ +void +AP4_PrintInspector::AddField(const char* name, AP4_UI64 value, FormatHint hint) +{ + char prefix[256]; + AP4_MakePrefixString(m_Indent, prefix, sizeof(prefix)); + m_Stream->WriteString(prefix); + + char str[32]; + AP4_FormatString(str, sizeof(str), + hint == HINT_HEX ? "%llx":"%lld", + value); + m_Stream->WriteString(name); + m_Stream->WriteString(" = "); + m_Stream->WriteString(str); + m_Stream->Write("\n", 1); +} + +/*---------------------------------------------------------------------- +| AP4_PrintInspector::AddFieldF ++---------------------------------------------------------------------*/ +void +AP4_PrintInspector::AddFieldF(const char* name, float value, FormatHint /*hint*/) +{ + char prefix[256]; + AP4_MakePrefixString(m_Indent, prefix, sizeof(prefix)); + m_Stream->WriteString(prefix); + + char str[32]; + AP4_FormatString(str, sizeof(str), + "%f", + value); + m_Stream->WriteString(name); + m_Stream->WriteString(" = "); + m_Stream->WriteString(str); + m_Stream->Write("\n", 1); +} + +/*---------------------------------------------------------------------- +| AP4_PrintInspector::AddField ++---------------------------------------------------------------------*/ +void +AP4_PrintInspector::AddField(const char* name, + const unsigned char* bytes, + AP4_Size byte_count, + FormatHint /* hint */) +{ + char prefix[256]; + AP4_MakePrefixString(m_Indent, prefix, sizeof(prefix)); + m_Stream->WriteString(prefix); + + m_Stream->WriteString(name); + m_Stream->WriteString(" = ["); + unsigned int offset = 1; + char byte[4]; + for (unsigned int i=0; i<byte_count; i++) { + AP4_FormatString(byte, 4, " %02x", bytes[i]); + m_Stream->Write(&byte[offset], 3-offset); + offset = 0; + } + m_Stream->Write("]\n", 2); +} + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Atom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Atom.h index e20b481fe..ee6120ac4 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Atom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Atom.h @@ -1,245 +1,443 @@ -/*****************************************************************
-|
-| AP4 - Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_ATOM_H_
-#define _AP4_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4Types.h"
-#include "Ap4List.h"
-#include "Ap4ByteStream.h"
-#include "Ap4Debug.h"
-
-/*----------------------------------------------------------------------
-| macros
-+---------------------------------------------------------------------*/
-#define AP4_ATOM_TYPE(a,b,c,d) \
- ((((unsigned long)a)<<24) | \
- (((unsigned long)b)<<16) | \
- (((unsigned long)c)<< 8) | \
- (((unsigned long)d) ))
-
-/*----------------------------------------------------------------------
-| constants
-+---------------------------------------------------------------------*/
-const int AP4_ATOM_HEADER_SIZE = 8;
-const int AP4_FULL_ATOM_HEADER_SIZE = 12;
-const int AP4_ATOM_MAX_NAME_SIZE = 256;
-const int AP4_ATOM_MAX_URI_SIZE = 512;
-
-/*----------------------------------------------------------------------
-| forward references
-+---------------------------------------------------------------------*/
-class AP4_AtomParent;
-
-/*----------------------------------------------------------------------
-| AP4_AtomInspector
-+---------------------------------------------------------------------*/
-class AP4_AtomInspector {
-public:
- // types
- typedef enum {
- HINT_NONE,
- HINT_HEX,
- HINT_BOOLEAN
- } FormatHint;
-
- // constructor and destructor
- AP4_AtomInspector() {}
- virtual ~AP4_AtomInspector() {}
-
- // methods
- virtual void StartElement(const char* name, const char* extra = NULL) {}
- virtual void EndElement() {}
- virtual void AddField(const char* name, AP4_UI32 value, FormatHint hint = HINT_NONE) {}
- virtual void AddField(const char* name, const char* value, FormatHint hint = HINT_NONE) {}
-};
-
-/*----------------------------------------------------------------------
-| AP4_Atom
-+---------------------------------------------------------------------*/
-class AP4_Atom {
- public:
- // types
- typedef AP4_UI32 Type;
-
- // methods
- AP4_Atom(Type type,
- bool is_full = false);
- AP4_Atom(Type type,
- AP4_Size size,
- bool is_full = false);
- AP4_Atom(Type type,
- AP4_Size size,
- bool is_full,
- AP4_ByteStream& stream);
- virtual ~AP4_Atom() {}
- Type GetType() { return m_Type; }
- void SetType(Type type) { m_Type = type; }
- AP4_Size GetHeaderSize();
- virtual AP4_Size GetSize() { return m_Size; }
- virtual AP4_Result Write(AP4_ByteStream& stream);
- virtual AP4_Result WriteHeader(AP4_ByteStream& stream);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream) = 0;
- virtual AP4_Result Inspect(AP4_AtomInspector& inspector);
- virtual AP4_Result InspectHeader(AP4_AtomInspector& inspector);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector) {
- return AP4_SUCCESS;
- }
-
- // parent/child realtionship methods
- virtual AP4_Result SetParent(AP4_AtomParent* parent) {
- m_Parent = parent;
- return AP4_SUCCESS;
- }
- virtual AP4_AtomParent* GetParent() { return m_Parent; }
- virtual AP4_Result Detach();
-
- // override this if your want to make an atom cloneable
- virtual AP4_Atom* Clone() { return NULL; }
-
- protected:
- // members
- Type m_Type;
- AP4_Size m_Size;
- bool m_IsFull;
- AP4_UI32 m_Version;
- AP4_UI32 m_Flags;
- AP4_AtomParent* m_Parent;
-};
-
-/*----------------------------------------------------------------------
-| AP4_AtomParent
-+---------------------------------------------------------------------*/
-class AP4_AtomParent {
-public:
- // base methods
- virtual ~AP4_AtomParent();
- AP4_List<AP4_Atom>& GetChildren() { return m_Children; }
- virtual AP4_Result AddChild(AP4_Atom* child, int position = -1);
- virtual AP4_Result RemoveChild(AP4_Atom* child);
- virtual AP4_Result DeleteChild(AP4_Atom::Type type);
- virtual AP4_Atom* GetChild(AP4_Atom::Type type, AP4_Ordinal index = 0);
- virtual AP4_Atom* FindChild(const char* path,
- bool auto_create = false);
-
- // methods designed to be overridden
- virtual void OnChildChanged(AP4_Atom* child) {}
- virtual void OnChildAdded(AP4_Atom* child) {}
- virtual void OnChildRemoved(AP4_Atom* child) {}
-
-protected:
- // members
- AP4_List<AP4_Atom> m_Children;
-};
-
-/*----------------------------------------------------------------------
-| AP4_UnknownAtom
-+---------------------------------------------------------------------*/
-class AP4_UnknownAtom : public AP4_Atom {
-public:
- // constructor and destructor
- AP4_UnknownAtom(AP4_Atom::Type type,
- AP4_Size size,
- bool is_full,
- AP4_ByteStream& stream);
- ~AP4_UnknownAtom();
-
- // methods
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
-
-private:
- // members
- AP4_ByteStream* m_SourceStream;
- AP4_Offset m_SourceOffset;
-};
-
-/*----------------------------------------------------------------------
-| atom types
-+---------------------------------------------------------------------*/
-const AP4_Atom::Type AP4_ATOM_TYPE_UDTA = AP4_ATOM_TYPE('u','d','t','a');
-const AP4_Atom::Type AP4_ATOM_TYPE_URL = AP4_ATOM_TYPE('u','r','l',' ');
-const AP4_Atom::Type AP4_ATOM_TYPE_TRAK = AP4_ATOM_TYPE('t','r','a','k');
-const AP4_Atom::Type AP4_ATOM_TYPE_TKHD = AP4_ATOM_TYPE('t','k','h','d');
-const AP4_Atom::Type AP4_ATOM_TYPE_STTS = AP4_ATOM_TYPE('s','t','t','s');
-const AP4_Atom::Type AP4_ATOM_TYPE_STSZ = AP4_ATOM_TYPE('s','t','s','z');
-const AP4_Atom::Type AP4_ATOM_TYPE_STSS = AP4_ATOM_TYPE('s','t','s','s');
-const AP4_Atom::Type AP4_ATOM_TYPE_STSD = AP4_ATOM_TYPE('s','t','s','d');
-const AP4_Atom::Type AP4_ATOM_TYPE_STSC = AP4_ATOM_TYPE('s','t','s','c');
-const AP4_Atom::Type AP4_ATOM_TYPE_STCO = AP4_ATOM_TYPE('s','t','c','o');
-const AP4_Atom::Type AP4_ATOM_TYPE_CO64 = AP4_ATOM_TYPE('c','o','6','4');
-const AP4_Atom::Type AP4_ATOM_TYPE_STBL = AP4_ATOM_TYPE('s','t','b','l');
-const AP4_Atom::Type AP4_ATOM_TYPE_SINF = AP4_ATOM_TYPE('s','i','n','f');
-const AP4_Atom::Type AP4_ATOM_TYPE_SCHM = AP4_ATOM_TYPE('s','c','h','m');
-const AP4_Atom::Type AP4_ATOM_TYPE_SCHI = AP4_ATOM_TYPE('s','c','h','i');
-const AP4_Atom::Type AP4_ATOM_TYPE_MVHD = AP4_ATOM_TYPE('m','v','h','d');
-const AP4_Atom::Type AP4_ATOM_TYPE_MP4S = AP4_ATOM_TYPE('m','p','4','s');
-const AP4_Atom::Type AP4_ATOM_TYPE_MP4A = AP4_ATOM_TYPE('m','p','4','a');
-const AP4_Atom::Type AP4_ATOM_TYPE_MP4V = AP4_ATOM_TYPE('m','p','4','v');
-const AP4_Atom::Type AP4_ATOM_TYPE_AVC1 = AP4_ATOM_TYPE('a','v','c','1');
-const AP4_Atom::Type AP4_ATOM_TYPE_ENCA = AP4_ATOM_TYPE('e','n','c','a');
-const AP4_Atom::Type AP4_ATOM_TYPE_ENCV = AP4_ATOM_TYPE('e','n','c','v');
-const AP4_Atom::Type AP4_ATOM_TYPE_MOOV = AP4_ATOM_TYPE('m','o','o','v');
-const AP4_Atom::Type AP4_ATOM_TYPE_MINF = AP4_ATOM_TYPE('m','i','n','f');
-const AP4_Atom::Type AP4_ATOM_TYPE_META = AP4_ATOM_TYPE('m','e','t','a');
-const AP4_Atom::Type AP4_ATOM_TYPE_MDHD = AP4_ATOM_TYPE('m','d','h','d');
-const AP4_Atom::Type AP4_ATOM_TYPE_ILST = AP4_ATOM_TYPE('i','l','s','t');
-const AP4_Atom::Type AP4_ATOM_TYPE_HDLR = AP4_ATOM_TYPE('h','d','l','r');
-const AP4_Atom::Type AP4_ATOM_TYPE_FTYP = AP4_ATOM_TYPE('f','t','y','p');
-const AP4_Atom::Type AP4_ATOM_TYPE_ESDS = AP4_ATOM_TYPE('e','s','d','s');
-const AP4_Atom::Type AP4_ATOM_TYPE_EDTS = AP4_ATOM_TYPE('e','d','t','s');
-const AP4_Atom::Type AP4_ATOM_TYPE_DRMS = AP4_ATOM_TYPE('d','r','m','s');
-const AP4_Atom::Type AP4_ATOM_TYPE_DREF = AP4_ATOM_TYPE('d','r','e','f');
-const AP4_Atom::Type AP4_ATOM_TYPE_DINF = AP4_ATOM_TYPE('d','i','n','f');
-const AP4_Atom::Type AP4_ATOM_TYPE_CTTS = AP4_ATOM_TYPE('c','t','t','s');
-const AP4_Atom::Type AP4_ATOM_TYPE_MDIA = AP4_ATOM_TYPE('m','d','i','a');
-const AP4_Atom::Type AP4_ATOM_TYPE_VMHD = AP4_ATOM_TYPE('v','m','h','d');
-const AP4_Atom::Type AP4_ATOM_TYPE_SMHD = AP4_ATOM_TYPE('s','m','h','d');
-const AP4_Atom::Type AP4_ATOM_TYPE_NMHD = AP4_ATOM_TYPE('n','m','h','d');
-const AP4_Atom::Type AP4_ATOM_TYPE_HMHD = AP4_ATOM_TYPE('h','m','h','d');
-const AP4_Atom::Type AP4_ATOM_TYPE_FRMA = AP4_ATOM_TYPE('f','r','m','a');
-const AP4_Atom::Type AP4_ATOM_TYPE_MDAT = AP4_ATOM_TYPE('m','d','a','t');
-const AP4_Atom::Type AP4_ATOM_TYPE_FREE = AP4_ATOM_TYPE('f','r','e','e');
-const AP4_Atom::Type AP4_ATOM_TYPE_TIMS = AP4_ATOM_TYPE('t','i','m','s');
-const AP4_Atom::Type AP4_ATOM_TYPE_RTP = AP4_ATOM_TYPE('r','t','p',' ');
-const AP4_Atom::Type AP4_ATOM_TYPE_HNTI = AP4_ATOM_TYPE('h','n','t','i');
-const AP4_Atom::Type AP4_ATOM_TYPE_SDP = AP4_ATOM_TYPE('s','d','p',' ');
-const AP4_Atom::Type AP4_ATOM_TYPE_IKMS = AP4_ATOM_TYPE('i','K','M','S');
-const AP4_Atom::Type AP4_ATOM_TYPE_ISFM = AP4_ATOM_TYPE('i','S','F','M');
-const AP4_Atom::Type AP4_ATOM_TYPE_HINT = AP4_ATOM_TYPE('h','i','n','t');
-const AP4_Atom::Type AP4_ATOM_TYPE_TREF = AP4_ATOM_TYPE('t','r','e','f');
-
-const AP4_Atom::Type AP4_ATOM_TYPE_AVCC = AP4_ATOM_TYPE('a','v','c','C');
+/***************************************************************** +| +| AP4 - 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 Atoms +*/ + +#ifndef _AP4_ATOM_H_ +#define _AP4_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4List.h" +#include "Ap4ByteStream.h" +#include "Ap4String.h" +#include "Ap4Debug.h" +#include "Ap4DynamicCast.h" + +/*---------------------------------------------------------------------- +| macros ++---------------------------------------------------------------------*/ +#define AP4_ATOM_TYPE(c1,c2,c3,c4) \ + ((((AP4_UI32)c1)<<24) | \ + (((AP4_UI32)c2)<<16) | \ + (((AP4_UI32)c3)<< 8) | \ + (((AP4_UI32)c4) )) + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_ATOM_HEADER_SIZE = 8; +const AP4_UI32 AP4_ATOM_HEADER_SIZE_64 = 16; +const AP4_UI32 AP4_FULL_ATOM_HEADER_SIZE = 12; +const AP4_UI32 AP4_FULL_ATOM_HEADER_SIZE_64 = 20; +const AP4_UI32 AP4_ATOM_MAX_NAME_SIZE = 256; +const AP4_UI32 AP4_ATOM_MAX_URI_SIZE = 512; + +/*---------------------------------------------------------------------- +| forward references ++---------------------------------------------------------------------*/ +class AP4_AtomParent; + +/*---------------------------------------------------------------------- +| AP4_AtomInspector ++---------------------------------------------------------------------*/ +/** + * Class used in a visitor pattern to walk all the atoms in a tree of + * #AP4_Atom objects. + */ +class AP4_AtomInspector { +public: + // types + typedef enum { + HINT_NONE = 0, + HINT_HEX = 1, + HINT_BOOLEAN = 2 + } FormatHint; + + // constructor and destructor + AP4_AtomInspector() {} + virtual ~AP4_AtomInspector() {} + + // methods + void SetVerbosity(AP4_Ordinal verbosity) { m_Verbosity = verbosity; } + AP4_Ordinal GetVerbosity() { return m_Verbosity; } + + // virtual methods + virtual void StartElement(const char* /* name */, + const char* /* extra = NULL */) {} + virtual void EndElement() {} + virtual void AddField(const char* /* name */, + AP4_UI64 /* value */, + FormatHint hint = HINT_NONE) { + (void)hint; // gcc warning + } + virtual void AddFieldF(const char* /* name */, + float /* value */, + FormatHint hint = HINT_NONE) { + (void)hint; // gcc warning + } + virtual void AddField(const char* /* name */, + const char* /* value */, + FormatHint hint = HINT_NONE) { + (void)hint; // gcc warning + } + virtual void AddField(const char* /* name */, + const unsigned char* /* bytes */, + AP4_Size /* byte_count */, + FormatHint hint = HINT_NONE) { + (void)hint; // gcc warning + } + +protected: + AP4_Ordinal m_Verbosity; +}; + +/*---------------------------------------------------------------------- +| AP4_PrintInspector ++---------------------------------------------------------------------*/ +class AP4_PrintInspector : public AP4_AtomInspector { +public: + AP4_PrintInspector(AP4_ByteStream& stream, AP4_Cardinal indent=0); + ~AP4_PrintInspector(); + + // methods + void StartElement(const char* name, const char* info); + void EndElement(); + void AddField(const char* name, AP4_UI64 value, FormatHint hint); + void AddFieldF(const char* name, float value, FormatHint hint); + void AddField(const char* name, const char* value, FormatHint hint); + void AddField(const char* name, const unsigned char* bytes, AP4_Size size, FormatHint hint); + +private: + // members + AP4_ByteStream* m_Stream; + AP4_Cardinal m_Indent; +}; + +/*---------------------------------------------------------------------- +| AP4_Atom ++---------------------------------------------------------------------*/ +/** + * Abstract base class for all atom types. + */ +class AP4_Atom { + public: + AP4_IMPLEMENT_DYNAMIC_CAST(AP4_Atom) + + // types + typedef AP4_UI32 Type; + + // class methods + static Type TypeFromString(const char* four_cc); + static AP4_Result ReadFullHeader(AP4_ByteStream& stream, + AP4_UI32& version, + AP4_UI32& flags); + + // constructors + /** + * Create a simple atom with a specified type and 32-bit size. + */ + explicit AP4_Atom(Type type, AP4_UI32 size = AP4_ATOM_HEADER_SIZE); + + /** + * Create a simple atom with a specified type and 64-bit size. + */ + explicit AP4_Atom(Type type, AP4_UI64 size, bool force_64=false); + + /** + * Create a full atom with a specified type, 32-bit size, version and flags. + */ + explicit AP4_Atom(Type type, + AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags); + + /** + * Create a full atom with a specified type, 64-bit size, version and flags. + */ + explicit AP4_Atom(Type type, + AP4_UI64 size, + bool force_64, + AP4_UI32 version, + AP4_UI32 flags); + + // destructor + virtual ~AP4_Atom() {} + + // methods + AP4_UI32 GetFlags() const { return m_Flags; } + void SetFlags(AP4_UI32 flags) { m_Flags = flags; } + Type GetType() const { return m_Type; } + void SetType(Type type) { m_Type = type; } + AP4_Size GetHeaderSize() const; + AP4_UI64 GetSize() const { return m_Size32 == 1?m_Size64:m_Size32; } + void SetSize(AP4_UI64 size, bool force_64 = false); + AP4_UI32 GetSize32() const { return m_Size32; } + void SetSize32(AP4_UI32 size) { m_Size32 = size; } + AP4_UI64 GetSize64() const { return m_Size64; } + void SetSize64(AP4_UI64 size) { m_Size64 = size; } + virtual AP4_Result Write(AP4_ByteStream& stream); + virtual AP4_Result WriteHeader(AP4_ByteStream& stream); + virtual AP4_Result WriteFields(AP4_ByteStream& stream) = 0; + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + virtual AP4_Result InspectHeader(AP4_AtomInspector& inspector); + virtual AP4_Result InspectFields(AP4_AtomInspector& /* inspector */) { + return AP4_SUCCESS; + } + + // parent/child relationship methods + virtual AP4_Result SetParent(AP4_AtomParent* parent) { + m_Parent = parent; + return AP4_SUCCESS; + } + virtual AP4_AtomParent* GetParent() { return m_Parent; } + virtual AP4_Result Detach(); + + /** + * Create a clone of the object. + * This method returns a clone of the atom, or NULL if + * the atom cannot be cloned. + * Override this if your want to make an atom cloneable in a more + * efficient way than the default implementation. + */ + virtual AP4_Atom* Clone(); + + protected: + // members + Type m_Type; + AP4_UI32 m_Size32; + AP4_UI64 m_Size64; // this is 0 if m_Size is not 1 (encoded in 32-bits) + // and non-zero only if m_Size is 1 (encoded in 64-bits) + bool m_IsFull; + AP4_UI32 m_Version; + AP4_UI32 m_Flags; + AP4_AtomParent* m_Parent; +}; + +/*---------------------------------------------------------------------- +| AP4_AtomParent ++---------------------------------------------------------------------*/ +/** + * Base class for containers of atoms. + * This class also implements the logic for finding descendents by name. + */ +class AP4_AtomParent { +public: + AP4_IMPLEMENT_DYNAMIC_CAST(AP4_AtomParent) + + // base methods + virtual ~AP4_AtomParent(); + AP4_List<AP4_Atom>& GetChildren() { return m_Children; } + virtual AP4_Result AddChild(AP4_Atom* child, int position = -1); + virtual AP4_Result RemoveChild(AP4_Atom* child); + virtual AP4_Result DeleteChild(AP4_Atom::Type type, AP4_Ordinal index = 0); + virtual AP4_Atom* GetChild(AP4_Atom::Type type, AP4_Ordinal index = 0) const; + virtual AP4_Atom* FindChild(const char* path, + bool auto_create = false, + bool auto_create_full = false); + + // methods designed to be overridden + virtual void OnChildChanged(AP4_Atom* /* child */) {} + virtual void OnChildAdded(AP4_Atom* /* child */) {} + virtual void OnChildRemoved(AP4_Atom* /* child */) {} + +protected: + // members + AP4_List<AP4_Atom> m_Children; +}; + +/*---------------------------------------------------------------------- +| AP4_UnknownAtom ++---------------------------------------------------------------------*/ +/** + * Class that represents atoms for which there is no specific support. + * Instances of this class keep a reference to the stream from which + * the atom is parsed, so that it can read the atom's payload when it + * is serialized. + */ +class AP4_UnknownAtom : public AP4_Atom { +public: + // constructor and destructor + AP4_UnknownAtom(AP4_Atom::Type type, + AP4_UI64 size, + AP4_ByteStream& stream); + ~AP4_UnknownAtom(); + + // methods + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Atom* Clone(); + +private: + // members + AP4_ByteStream* m_SourceStream; + AP4_Position m_SourcePosition; +}; + +/*---------------------------------------------------------------------- +| AP4_NullTerminatedStringAtom ++---------------------------------------------------------------------*/ +/** + * Generic Class usd for all atoms that contain a single null-terminated + * string. + */ +class AP4_NullTerminatedStringAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_NullTerminatedStringAtom, AP4_Atom) + + // constructors + AP4_NullTerminatedStringAtom(AP4_Atom::Type type, AP4_UI64 size, AP4_ByteStream& stream); + AP4_NullTerminatedStringAtom(AP4_Atom::Type type, const char* value); + + // accessors + const AP4_String& GetValue() { return m_Value; } + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // members + AP4_String m_Value; +}; + +/*---------------------------------------------------------------------- +| atom types ++---------------------------------------------------------------------*/ +const AP4_Atom::Type AP4_ATOM_TYPE_UDTA = AP4_ATOM_TYPE('u','d','t','a'); +const AP4_Atom::Type AP4_ATOM_TYPE_URL = AP4_ATOM_TYPE('u','r','l',' '); +const AP4_Atom::Type AP4_ATOM_TYPE_TRAK = AP4_ATOM_TYPE('t','r','a','k'); +const AP4_Atom::Type AP4_ATOM_TYPE_TRAF = AP4_ATOM_TYPE('t','r','a','f'); +const AP4_Atom::Type AP4_ATOM_TYPE_TKHD = AP4_ATOM_TYPE('t','k','h','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_TFHD = AP4_ATOM_TYPE('t','f','h','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_TRUN = AP4_ATOM_TYPE('t','r','u','n'); +const AP4_Atom::Type AP4_ATOM_TYPE_STTS = AP4_ATOM_TYPE('s','t','t','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_STSZ = AP4_ATOM_TYPE('s','t','s','z'); +const AP4_Atom::Type AP4_ATOM_TYPE_STSS = AP4_ATOM_TYPE('s','t','s','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_STSD = AP4_ATOM_TYPE('s','t','s','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_STSC = AP4_ATOM_TYPE('s','t','s','c'); +const AP4_Atom::Type AP4_ATOM_TYPE_STCO = AP4_ATOM_TYPE('s','t','c','o'); +const AP4_Atom::Type AP4_ATOM_TYPE_CO64 = AP4_ATOM_TYPE('c','o','6','4'); +const AP4_Atom::Type AP4_ATOM_TYPE_STBL = AP4_ATOM_TYPE('s','t','b','l'); +const AP4_Atom::Type AP4_ATOM_TYPE_SINF = AP4_ATOM_TYPE('s','i','n','f'); +const AP4_Atom::Type AP4_ATOM_TYPE_SCHM = AP4_ATOM_TYPE('s','c','h','m'); +const AP4_Atom::Type AP4_ATOM_TYPE_SCHI = AP4_ATOM_TYPE('s','c','h','i'); +const AP4_Atom::Type AP4_ATOM_TYPE_MVHD = AP4_ATOM_TYPE('m','v','h','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_MP4S = AP4_ATOM_TYPE('m','p','4','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_MP4A = AP4_ATOM_TYPE('m','p','4','a'); +const AP4_Atom::Type AP4_ATOM_TYPE_MP4V = AP4_ATOM_TYPE('m','p','4','v'); +const AP4_Atom::Type AP4_ATOM_TYPE_AVC1 = AP4_ATOM_TYPE('a','v','c','1'); +const AP4_Atom::Type AP4_ATOM_TYPE_ALAC = AP4_ATOM_TYPE('a','l','a','c'); +const AP4_Atom::Type AP4_ATOM_TYPE_ENCA = AP4_ATOM_TYPE('e','n','c','a'); +const AP4_Atom::Type AP4_ATOM_TYPE_ENCV = AP4_ATOM_TYPE('e','n','c','v'); +const AP4_Atom::Type AP4_ATOM_TYPE_MOOV = AP4_ATOM_TYPE('m','o','o','v'); +const AP4_Atom::Type AP4_ATOM_TYPE_MOOF = AP4_ATOM_TYPE('m','o','o','f'); +const AP4_Atom::Type AP4_ATOM_TYPE_MVEX = AP4_ATOM_TYPE('m','v','e','x'); +const AP4_Atom::Type AP4_ATOM_TYPE_MINF = AP4_ATOM_TYPE('m','i','n','f'); +const AP4_Atom::Type AP4_ATOM_TYPE_META = AP4_ATOM_TYPE('m','e','t','a'); +const AP4_Atom::Type AP4_ATOM_TYPE_MDHD = AP4_ATOM_TYPE('m','d','h','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_MFHD = AP4_ATOM_TYPE('m','f','h','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_ILST = AP4_ATOM_TYPE('i','l','s','t'); +const AP4_Atom::Type AP4_ATOM_TYPE_HDLR = AP4_ATOM_TYPE('h','d','l','r'); +const AP4_Atom::Type AP4_ATOM_TYPE_FTYP = AP4_ATOM_TYPE('f','t','y','p'); +const AP4_Atom::Type AP4_ATOM_TYPE_IODS = AP4_ATOM_TYPE('i','o','d','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_ESDS = AP4_ATOM_TYPE('e','s','d','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_EDTS = AP4_ATOM_TYPE('e','d','t','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_DRMS = AP4_ATOM_TYPE('d','r','m','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_DRMI = AP4_ATOM_TYPE('d','r','m','i'); +const AP4_Atom::Type AP4_ATOM_TYPE_DREF = AP4_ATOM_TYPE('d','r','e','f'); +const AP4_Atom::Type AP4_ATOM_TYPE_DINF = AP4_ATOM_TYPE('d','i','n','f'); +const AP4_Atom::Type AP4_ATOM_TYPE_CTTS = AP4_ATOM_TYPE('c','t','t','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_MDIA = AP4_ATOM_TYPE('m','d','i','a'); +const AP4_Atom::Type AP4_ATOM_TYPE_ELST = AP4_ATOM_TYPE('e','l','s','t'); +const AP4_Atom::Type AP4_ATOM_TYPE_VMHD = AP4_ATOM_TYPE('v','m','h','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_SMHD = AP4_ATOM_TYPE('s','m','h','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_NMHD = AP4_ATOM_TYPE('n','m','h','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_HMHD = AP4_ATOM_TYPE('h','m','h','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_FRMA = AP4_ATOM_TYPE('f','r','m','a'); +const AP4_Atom::Type AP4_ATOM_TYPE_MDAT = AP4_ATOM_TYPE('m','d','a','t'); +const AP4_Atom::Type AP4_ATOM_TYPE_FREE = AP4_ATOM_TYPE('f','r','e','e'); +const AP4_Atom::Type AP4_ATOM_TYPE_TIMS = AP4_ATOM_TYPE('t','i','m','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_RTP_ = AP4_ATOM_TYPE('r','t','p',' '); +const AP4_Atom::Type AP4_ATOM_TYPE_HNTI = AP4_ATOM_TYPE('h','n','t','i'); +const AP4_Atom::Type AP4_ATOM_TYPE_SDP_ = AP4_ATOM_TYPE('s','d','p',' '); +const AP4_Atom::Type AP4_ATOM_TYPE_IKMS = AP4_ATOM_TYPE('i','K','M','S'); +const AP4_Atom::Type AP4_ATOM_TYPE_ISFM = AP4_ATOM_TYPE('i','S','F','M'); +const AP4_Atom::Type AP4_ATOM_TYPE_ISLT = AP4_ATOM_TYPE('i','S','L','T'); +const AP4_Atom::Type AP4_ATOM_TYPE_TREF = AP4_ATOM_TYPE('t','r','e','f'); +const AP4_Atom::Type AP4_ATOM_TYPE_HINT = AP4_ATOM_TYPE('h','i','n','t'); +const AP4_Atom::Type AP4_ATOM_TYPE_CDSC = AP4_ATOM_TYPE('c','d','s','c'); +const AP4_Atom::Type AP4_ATOM_TYPE_MPOD = AP4_ATOM_TYPE('m','p','o','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_IPIR = AP4_ATOM_TYPE('i','p','i','r'); +const AP4_Atom::Type AP4_ATOM_TYPE_CHAP = AP4_ATOM_TYPE('c','h','a','p'); +const AP4_Atom::Type AP4_ATOM_TYPE_ALIS = AP4_ATOM_TYPE('a','l','i','s'); +const AP4_Atom::Type AP4_ATOM_TYPE_SYNC = AP4_ATOM_TYPE('s','y','n','c'); +const AP4_Atom::Type AP4_ATOM_TYPE_DPND = AP4_ATOM_TYPE('d','p','n','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_ODRM = AP4_ATOM_TYPE('o','d','r','m'); +const AP4_Atom::Type AP4_ATOM_TYPE_ODKM = AP4_ATOM_TYPE('o','d','k','m'); +const AP4_Atom::Type AP4_ATOM_TYPE_OHDR = AP4_ATOM_TYPE('o','h','d','r'); +const AP4_Atom::Type AP4_ATOM_TYPE_ODDA = AP4_ATOM_TYPE('o','d','d','a'); +const AP4_Atom::Type AP4_ATOM_TYPE_ODHE = AP4_ATOM_TYPE('o','d','h','e'); +const AP4_Atom::Type AP4_ATOM_TYPE_ODAF = AP4_ATOM_TYPE('o','d','a','f'); +const AP4_Atom::Type AP4_ATOM_TYPE_GRPI = AP4_ATOM_TYPE('g','r','p','i'); +const AP4_Atom::Type AP4_ATOM_TYPE_IPRO = AP4_ATOM_TYPE('i','p','r','o'); +const AP4_Atom::Type AP4_ATOM_TYPE_MDRI = AP4_ATOM_TYPE('m','d','r','i'); +const AP4_Atom::Type AP4_ATOM_TYPE_AVCC = AP4_ATOM_TYPE('a','v','c','C'); +const AP4_Atom::Type AP4_ATOM_TYPE_WAVE = AP4_ATOM_TYPE('w','a','v','e'); +const AP4_Atom::Type AP4_ATOM_TYPE_WIDE = AP4_ATOM_TYPE('w','i','d','e'); +const AP4_Atom::Type AP4_ATOM_TYPE_UUID = AP4_ATOM_TYPE('u','u','i','d'); +const AP4_Atom::Type AP4_ATOM_TYPE_8ID_ = AP4_ATOM_TYPE('8','i','d',' '); +const AP4_Atom::Type AP4_ATOM_TYPE_8BDL = AP4_ATOM_TYPE('8','b','d','l'); + +// ==> Start patch MPC +const AP4_Atom::Type AP4_ATOM_TYPE_FTAB = AP4_ATOM_TYPE('f','t','a','b');
+const AP4_Atom::Type AP4_ATOM_TYPE_CHPL = AP4_ATOM_TYPE('c','h','p','l');
+const AP4_Atom::Type AP4_ATOM_TYPE__AC3 = AP4_ATOM_TYPE('a','c','-','3');
+const AP4_Atom::Type AP4_ATOM_TYPE_SAC3 = AP4_ATOM_TYPE('s','a','c','3');
+const AP4_Atom::Type AP4_ATOM_TYPE_EAC3 = AP4_ATOM_TYPE('e','c','-','3');
+const AP4_Atom::Type AP4_ATOM_TYPE_DTSC = AP4_ATOM_TYPE('d','t','s','c');
+const AP4_Atom::Type AP4_ATOM_TYPE_DTSH = AP4_ATOM_TYPE('d','t','s','h');
+const AP4_Atom::Type AP4_ATOM_TYPE_DTSL = AP4_ATOM_TYPE('d','t','s','l');
+const AP4_Atom::Type AP4_ATOM_TYPE__MP3 = AP4_ATOM_TYPE('.','m','p','3');
+const AP4_Atom::Type AP4_ATOM_TYPE_NAM = AP4_ATOM_TYPE(169,'n','a','m');
+const AP4_Atom::Type AP4_ATOM_TYPE_ART = AP4_ATOM_TYPE(169,'A','R','T');
+const AP4_Atom::Type AP4_ATOM_TYPE_WRT = AP4_ATOM_TYPE(169,'w','r','t');
+const AP4_Atom::Type AP4_ATOM_TYPE_ALB = AP4_ATOM_TYPE(169,'a','l','b');
+const AP4_Atom::Type AP4_ATOM_TYPE_DAY = AP4_ATOM_TYPE(169,'d','a','y');
+const AP4_Atom::Type AP4_ATOM_TYPE_TOO = AP4_ATOM_TYPE(169,'t','o','o');
+const AP4_Atom::Type AP4_ATOM_TYPE_CMT = AP4_ATOM_TYPE(169,'c','m','t');
+const AP4_Atom::Type AP4_ATOM_TYPE_GEN = AP4_ATOM_TYPE(169,'g','e','n');
const AP4_Atom::Type AP4_ATOM_TYPE_TEXT = AP4_ATOM_TYPE('t','e','x','t');
const AP4_Atom::Type AP4_ATOM_TYPE_TX3G = AP4_ATOM_TYPE('t','x','3','g');
-const AP4_Atom::Type AP4_ATOM_TYPE_FTAB = AP4_ATOM_TYPE('f','t','a','b');
const AP4_Atom::Type AP4_ATOM_TYPE_CVID = AP4_ATOM_TYPE('c','v','i','d');
const AP4_Atom::Type AP4_ATOM_TYPE_SVQ1 = AP4_ATOM_TYPE('S','V','Q','1');
const AP4_Atom::Type AP4_ATOM_TYPE_SVQ2 = AP4_ATOM_TYPE('S','V','Q','2');
@@ -247,105 +445,81 @@ const AP4_Atom::Type AP4_ATOM_TYPE_SVQ3 = AP4_ATOM_TYPE('S','V','Q','3'); const AP4_Atom::Type AP4_ATOM_TYPE_H263 = AP4_ATOM_TYPE('h','2','6','3');
const AP4_Atom::Type AP4_ATOM_TYPE_S263 = AP4_ATOM_TYPE('s','2','6','3');
const AP4_Atom::Type AP4_ATOM_TYPE_SAMR = AP4_ATOM_TYPE('s','a','m','r');
-const AP4_Atom::Type AP4_ATOM_TYPE__MP3 = AP4_ATOM_TYPE('.','m','p','3');
const AP4_Atom::Type AP4_ATOM_TYPE_IMA4 = AP4_ATOM_TYPE('i','m','a','4');
const AP4_Atom::Type AP4_ATOM_TYPE_QDMC = AP4_ATOM_TYPE('Q','D','M','C');
const AP4_Atom::Type AP4_ATOM_TYPE_QDM2 = AP4_ATOM_TYPE('Q','D','M','2');
const AP4_Atom::Type AP4_ATOM_TYPE_TWOS = AP4_ATOM_TYPE('t','w','o','s');
const AP4_Atom::Type AP4_ATOM_TYPE_SOWT = AP4_ATOM_TYPE('s','o','w','t');
-const AP4_Atom::Type AP4_ATOM_TYPE_CHPL = AP4_ATOM_TYPE('c','h','p','l');
-const AP4_Atom::Type AP4_ATOM_TYPE_NAM = AP4_ATOM_TYPE(169,'n','a','m');
-const AP4_Atom::Type AP4_ATOM_TYPE_ART = AP4_ATOM_TYPE(169,'A','R','T');
-const AP4_Atom::Type AP4_ATOM_TYPE_WRT = AP4_ATOM_TYPE(169,'w','r','t');
-const AP4_Atom::Type AP4_ATOM_TYPE_ALB = AP4_ATOM_TYPE(169,'a','l','b');
-const AP4_Atom::Type AP4_ATOM_TYPE_DAY = AP4_ATOM_TYPE(169,'d','a','y');
-const AP4_Atom::Type AP4_ATOM_TYPE_TOO = AP4_ATOM_TYPE(169,'t','o','o');
-const AP4_Atom::Type AP4_ATOM_TYPE_CMT = AP4_ATOM_TYPE(169,'c','m','t');
-const AP4_Atom::Type AP4_ATOM_TYPE_GEN = AP4_ATOM_TYPE(169,'g','e','n');
-const AP4_Atom::Type AP4_ATOM_TYPE_TRKN = AP4_ATOM_TYPE('t','r','k','n');
-const AP4_Atom::Type AP4_ATOM_TYPE_DATA = AP4_ATOM_TYPE('d','a','t','a');
-const AP4_Atom::Type AP4_ATOM_TYPE_WAVE = AP4_ATOM_TYPE('w','a','v','e');
-const AP4_Atom::Type AP4_ATOM_TYPE_CMOV = AP4_ATOM_TYPE('c','m','o','v');
-const AP4_Atom::Type AP4_ATOM_TYPE_DCOM = AP4_ATOM_TYPE('d','c','o','m');
-const AP4_Atom::Type AP4_ATOM_TYPE_CMVD = AP4_ATOM_TYPE('c','m','v','d');
-const AP4_Atom::Type AP4_ATOM_TYPE__AC3 = AP4_ATOM_TYPE('a','c','-','3');
-const AP4_Atom::Type AP4_ATOM_TYPE_SAC3 = AP4_ATOM_TYPE('s','a','c','3');
-const AP4_Atom::Type AP4_ATOM_TYPE_EAC3 = AP4_ATOM_TYPE('e','c','-','3');
-const AP4_Atom::Type AP4_ATOM_TYPE_DTSC = AP4_ATOM_TYPE('d','t','s','c');
-const AP4_Atom::Type AP4_ATOM_TYPE_DTSH = AP4_ATOM_TYPE('d','t','s','h');
-const AP4_Atom::Type AP4_ATOM_TYPE_DTSL = AP4_ATOM_TYPE('d','t','s','l');
-
-/*----------------------------------------------------------------------
-| AP4_AtomListInspector
-+---------------------------------------------------------------------*/
-class AP4_AtomListInspector : public AP4_List<AP4_Atom>::Item::Operator
-{
- public:
- AP4_AtomListInspector(AP4_AtomInspector& inspector) :
- m_Inspector(inspector) {}
- AP4_Result Action(AP4_Atom* atom) const {
- atom->Inspect(m_Inspector);
- return AP4_SUCCESS;
- }
-
- private:
- AP4_AtomInspector& m_Inspector;
-};
-
-/*----------------------------------------------------------------------
-| AP4_AtomListWriter
-+---------------------------------------------------------------------*/
-class AP4_AtomListWriter : public AP4_List<AP4_Atom>::Item::Operator
-{
- public:
- AP4_AtomListWriter(AP4_ByteStream& stream) :
- m_Stream(stream) {}
- AP4_Result Action(AP4_Atom* atom) const {
- atom->Write(m_Stream);
- return AP4_SUCCESS;
- }
-
- private:
- AP4_ByteStream& m_Stream;
-};
-
-/*----------------------------------------------------------------------
-| AP4_AtomFinder
-+---------------------------------------------------------------------*/
-class AP4_AtomFinder : public AP4_List<AP4_Atom>::Item::Finder
-{
- public:
- AP4_AtomFinder(AP4_Atom::Type type, AP4_Ordinal index = 0) :
- m_Type(type), m_Index(index) {}
- AP4_Result Test(AP4_Atom* atom) const {
- if (atom->GetType() == m_Type) {
- if (m_Index-- == 0) {
- return AP4_SUCCESS;
- } else {
- return AP4_FAILURE;
- }
- } else {
- return AP4_FAILURE;
- }
- }
- private:
- AP4_Atom::Type m_Type;
- mutable AP4_Ordinal m_Index;
-};
-
-/*----------------------------------------------------------------------
-| AP4_AtomSizeAdder
-+---------------------------------------------------------------------*/
-class AP4_AtomSizeAdder : public AP4_List<AP4_Atom>::Item::Operator {
-public:
- AP4_AtomSizeAdder(AP4_Size& size) : m_Size(size) {}
-
-private:
- AP4_Result Action(AP4_Atom* atom) const {
- m_Size += atom->GetSize();
- return AP4_SUCCESS;
- }
- AP4_Size& m_Size;
-};
-
-#endif // _AP4_ATOM_H_
+// <== End patch MPC + +/*---------------------------------------------------------------------- +| AP4_AtomListInspector ++---------------------------------------------------------------------*/ +class AP4_AtomListInspector : public AP4_List<AP4_Atom>::Item::Operator +{ + public: + AP4_AtomListInspector(AP4_AtomInspector& inspector) : + m_Inspector(inspector) {} + AP4_Result Action(AP4_Atom* atom) const { + atom->Inspect(m_Inspector); + return AP4_SUCCESS; + } + + private: + AP4_AtomInspector& m_Inspector; +}; + +/*---------------------------------------------------------------------- +| AP4_AtomListWriter ++---------------------------------------------------------------------*/ +class AP4_AtomListWriter : public AP4_List<AP4_Atom>::Item::Operator +{ + public: + AP4_AtomListWriter(AP4_ByteStream& stream) : + m_Stream(stream) {} + AP4_Result Action(AP4_Atom* atom) const; + + private: + AP4_ByteStream& m_Stream; +}; + +/*---------------------------------------------------------------------- +| AP4_AtomFinder ++---------------------------------------------------------------------*/ +class AP4_AtomFinder : public AP4_List<AP4_Atom>::Item::Finder +{ + public: + AP4_AtomFinder(AP4_Atom::Type type, AP4_Ordinal index = 0) : + m_Type(type), m_Index(index) {} + AP4_Result Test(AP4_Atom* atom) const { + if (atom->GetType() == m_Type) { + if (m_Index-- == 0) { + return AP4_SUCCESS; + } else { + return AP4_FAILURE; + } + } else { + return AP4_FAILURE; + } + } + private: + AP4_Atom::Type m_Type; + mutable AP4_Ordinal m_Index; +}; + +/*---------------------------------------------------------------------- +| AP4_AtomSizeAdder ++---------------------------------------------------------------------*/ +class AP4_AtomSizeAdder : public AP4_List<AP4_Atom>::Item::Operator { +public: + AP4_AtomSizeAdder(AP4_UI64& size) : m_Size(size) {} + +private: + AP4_Result Action(AP4_Atom* atom) const { + m_Size += atom->GetSize(); + return AP4_SUCCESS; + } + AP4_UI64& m_Size; +}; + +#endif // _AP4_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomFactory.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomFactory.cpp index eafdba81c..3261a21c8 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomFactory.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomFactory.cpp @@ -1,385 +1,558 @@ -/*****************************************************************
-|
-| AP4 - Atom Factory
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4SampleEntry.h"
-#include "Ap4IsmaCryp.h"
-#include "Ap4UrlAtom.h"
-#include "Ap4MoovAtom.h"
-#include "Ap4MvhdAtom.h"
-#include "Ap4TrakAtom.h"
-#include "Ap4HdlrAtom.h"
-#include "Ap4DrefAtom.h"
-#include "Ap4TkhdAtom.h"
-#include "Ap4MdhdAtom.h"
-#include "Ap4StsdAtom.h"
-#include "Ap4StscAtom.h"
-#include "Ap4StcoAtom.h"
-#include "Ap4Co64Atom.h"
-#include "Ap4StszAtom.h"
-#include "Ap4EsdsAtom.h"
-#include "Ap4SttsAtom.h"
-#include "Ap4CttsAtom.h"
-#include "Ap4StssAtom.h"
-#include "Ap4FtypAtom.h"
-#include "Ap4VmhdAtom.h"
-#include "Ap4SmhdAtom.h"
-#include "Ap4NmhdAtom.h"
-#include "Ap4HmhdAtom.h"
-#include "Ap4SchmAtom.h"
-#include "Ap4FrmaAtom.h"
-#include "Ap4TimsAtom.h"
-#include "Ap4RtpAtom.h"
-#include "Ap4SdpAtom.h"
-#include "Ap4IkmsAtom.h"
-#include "Ap4IsfmAtom.h"
-#include "Ap4TrefTypeAtom.h"
-#include "Ap4AvcCAtom.h"
-#include "Ap4FtabAtom.h"
-#include "Ap4ChplAtom.h"
-#include "Ap4DataAtom.h"
-#include "Ap4DcomAtom.h"
-#include "Ap4CmvdAtom.h"
-
-/*----------------------------------------------------------------------
-| class variables
-+---------------------------------------------------------------------*/
-AP4_AtomFactory AP4_AtomFactory::DefaultFactory;
-
-/*----------------------------------------------------------------------
-| AP4_AtomFactory::AddTypeHandler
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomFactory::AddTypeHandler(TypeHandler* handler)
-{
- return m_TypeHandlers.Add(handler);
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomFactory::RemoveTypeHandler
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomFactory::RemoveTypeHandler(TypeHandler* handler)
-{
- return m_TypeHandlers.Remove(handler);
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomFactory::CreateAtomFromStream
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream,
- AP4_Atom*& atom)
-{
- AP4_Size bytes_available = 0;
- if (AP4_FAILED(stream.GetSize(bytes_available)) ||
- bytes_available == 0) {
- bytes_available = (AP4_Size)((unsigned long)(-1));
- }
- return CreateAtomFromStream(stream, bytes_available, atom, NULL);
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomFactory::CreateAtomFromStream
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream,
- AP4_Size& bytes_available,
- AP4_Atom*& atom,
- AP4_Atom* parent)
-{
- AP4_Result result;
-
- // NULL by default
- atom = NULL;
-
- // check that there are enough bytes for at least a header
- if (bytes_available < 8) return AP4_ERROR_EOS;
-
- // remember current stream offset
- AP4_Offset start;
- stream.Tell(start);
-
- // read atom size
- AP4_UI32 size;
- result = stream.ReadUI32(size);
- if (AP4_FAILED(result)) {
- stream.Seek(start);
- return result;
- }
-
- if (size == 0) {
- // atom extends to end of file
- AP4_Size streamSize = 0;
- stream.GetSize(streamSize);
- if (streamSize >= start) {
- size = streamSize - start;
- }
- }
-
- // check the size (we don't handle extended size yet)
- if (size != 1 && size < 8 || size > bytes_available) {
- stream.Seek(start);
- return AP4_ERROR_INVALID_FORMAT;
- }
-
- // read atom type
- AP4_Atom::Type type;
- result = stream.ReadUI32(type);
- if (AP4_FAILED(result)) {
- stream.Seek(start);
- return result;
- }
-
- if (size == 1)
- {
- AP4_UI32 size_high;
-
- result = stream.ReadUI32(size_high);
- if (AP4_FAILED(result) || size_high) {
- stream.Seek(start);
- return AP4_ERROR_INVALID_FORMAT;
- }
-
- result = stream.ReadUI32(size);
- if (AP4_FAILED(result)) {
- stream.Seek(start);
- return result;
- }
- }
-
- // create the atom
- switch (type) {
- case AP4_ATOM_TYPE_MOOV:
- atom = DNew AP4_MoovAtom(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_MVHD:
- atom = DNew AP4_MvhdAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_TRAK:
- atom = DNew AP4_TrakAtom(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_HDLR:
- atom = DNew AP4_HdlrAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_DREF:
- atom = DNew AP4_DrefAtom(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_URL:
- atom = DNew AP4_UrlAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_TKHD:
- atom = DNew AP4_TkhdAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_MDHD:
- atom = DNew AP4_MdhdAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_STSD:
- atom = DNew AP4_StsdAtom(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_STSC:
- atom = DNew AP4_StscAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_STCO:
- atom = DNew AP4_StcoAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_CO64:
- atom = DNew AP4_Co64Atom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_STSZ:
- atom = DNew AP4_StszAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_STTS:
- atom = DNew AP4_SttsAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_CTTS:
- atom = DNew AP4_CttsAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_STSS:
- atom = DNew AP4_StssAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_MP4S:
- atom = DNew AP4_Mp4sSampleEntry(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_MP4A:
- atom = parent && parent->GetType() == AP4_ATOM_TYPE_STSD
- ? (AP4_Atom*)DNew AP4_Mp4aSampleEntry(size, stream, *this)
- : (AP4_Atom*)DNew AP4_UnknownAtom(type, size, false, stream);
- break;
-
- case AP4_ATOM_TYPE_MP4V:
- atom = DNew AP4_Mp4vSampleEntry(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_AVC1:
- atom = DNew AP4_Avc1SampleEntry(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_ENCA:
- atom = DNew AP4_EncaSampleEntry(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_ENCV:
- atom = DNew AP4_EncvSampleEntry(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_ESDS:
- atom = DNew AP4_EsdsAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_VMHD:
- atom = DNew AP4_VmhdAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_SMHD:
- atom = DNew AP4_SmhdAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_NMHD:
- atom = DNew AP4_NmhdAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_HMHD:
- atom = DNew AP4_HmhdAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_FRMA:
- atom = DNew AP4_FrmaAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_SCHM:
- atom = DNew AP4_SchmAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_FTYP:
- atom = DNew AP4_FtypAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_RTP:
- if (m_Context == AP4_ATOM_TYPE_HNTI) {
- atom = DNew AP4_RtpAtom(size, stream);
- } else {
- atom = DNew AP4_RtpHintSampleEntry(size, stream, *this);
- }
- break;
-
- case AP4_ATOM_TYPE_TIMS:
- atom = DNew AP4_TimsAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_SDP:
- atom = DNew AP4_SdpAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_IKMS:
- atom = DNew AP4_IkmsAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_ISFM:
- atom = DNew AP4_IsfmAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_HINT:
- atom = DNew AP4_TrefTypeAtom(type, size, stream);
- break;
-
- // container atoms
- case AP4_ATOM_TYPE_TREF:
- case AP4_ATOM_TYPE_HNTI:
- case AP4_ATOM_TYPE_STBL:
- case AP4_ATOM_TYPE_MDIA:
- case AP4_ATOM_TYPE_DINF:
- case AP4_ATOM_TYPE_MINF:
- case AP4_ATOM_TYPE_SCHI:
- case AP4_ATOM_TYPE_SINF:
- case AP4_ATOM_TYPE_UDTA:
- case AP4_ATOM_TYPE_ILST:
- case AP4_ATOM_TYPE_NAM:
- case AP4_ATOM_TYPE_ART:
- case AP4_ATOM_TYPE_WRT:
- case AP4_ATOM_TYPE_ALB:
- case AP4_ATOM_TYPE_DAY:
- case AP4_ATOM_TYPE_TOO:
- case AP4_ATOM_TYPE_CMT:
- case AP4_ATOM_TYPE_GEN:
- case AP4_ATOM_TYPE_TRKN:
- case AP4_ATOM_TYPE_EDTS:
- case AP4_ATOM_TYPE_WAVE:
- case AP4_ATOM_TYPE_CMOV: {
- AP4_UI32 context = m_Context;
- m_Context = type; // set the context for the children
- atom = DNew AP4_ContainerAtom(type, size, false, stream, *this);
- m_Context = context; // restore the previous context
- break;
- }
-
- // full container atoms
- case AP4_ATOM_TYPE_META:
- atom = DNew AP4_ContainerAtom(type, size, true, stream, *this);
- break;
-
- // other
-
- case AP4_ATOM_TYPE_AVCC:
- atom = DNew AP4_AvcCAtom(size, stream);
- break;
-
+/***************************************************************** +| +| AP4 - Atom Factory +| +| 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 "Ap4AtomFactory.h" +#include "Ap4SampleEntry.h" +#include "Ap4UuidAtom.h" +#include "Ap4IsmaCryp.h" +#include "Ap4UrlAtom.h" +#include "Ap4MoovAtom.h" +#include "Ap4MvhdAtom.h" +#include "Ap4MfhdAtom.h" +#include "Ap4TfhdAtom.h" +#include "Ap4TrunAtom.h" +#include "Ap4TrakAtom.h" +#include "Ap4HdlrAtom.h" +#include "Ap4DrefAtom.h" +#include "Ap4TkhdAtom.h" +#include "Ap4TfhdAtom.h" +#include "Ap4MdhdAtom.h" +#include "Ap4StsdAtom.h" +#include "Ap4StscAtom.h" +#include "Ap4StcoAtom.h" +#include "Ap4Co64Atom.h" +#include "Ap4StszAtom.h" +#include "Ap4IodsAtom.h" +#include "Ap4EsdsAtom.h" +#include "Ap4SttsAtom.h" +#include "Ap4CttsAtom.h" +#include "Ap4StssAtom.h" +#include "Ap4FtypAtom.h" +#include "Ap4VmhdAtom.h" +#include "Ap4SmhdAtom.h" +#include "Ap4NmhdAtom.h" +#include "Ap4HmhdAtom.h" +#include "Ap4ElstAtom.h" +#include "Ap4SchmAtom.h" +#include "Ap4FrmaAtom.h" +#include "Ap4TimsAtom.h" +#include "Ap4RtpAtom.h" +#include "Ap4SdpAtom.h" +#include "Ap4IkmsAtom.h" +#include "Ap4IsfmAtom.h" +#include "Ap4IsltAtom.h" +#include "Ap4OdheAtom.h" +#include "Ap4OhdrAtom.h" +#include "Ap4OddaAtom.h" +#include "Ap4TrefTypeAtom.h" +#include "Ap4MetaData.h" +#include "Ap4IproAtom.h" +#include "Ap4OdafAtom.h" +#include "Ap4GrpiAtom.h" +#include "Ap4AvccAtom.h" +#include "Ap4Marlin.h" +#include "Ap48bdlAtom.h" +// ==> Start patch MPC +#include "Ap4FtabAtom.h" +// <== End patch MPC + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::~AP4_AtomFactory ++---------------------------------------------------------------------*/ +AP4_AtomFactory::~AP4_AtomFactory() +{ + m_TypeHandlers.DeleteReferences(); +} + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::AddTypeHandler ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomFactory::AddTypeHandler(TypeHandler* handler) +{ + return m_TypeHandlers.Add(handler); +} + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::RemoveTypeHandler ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomFactory::RemoveTypeHandler(TypeHandler* handler) +{ + return m_TypeHandlers.Remove(handler); +} + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::CreateAtomFromStream ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream, + AP4_Atom*& atom) +{ + AP4_LargeSize stream_size = 0; + AP4_Position stream_position = 0; + AP4_LargeSize bytes_available = (AP4_LargeSize)(-1); + if (AP4_SUCCEEDED(stream.GetSize(stream_size)) && + stream_size != 0 && + AP4_SUCCEEDED(stream.Tell(stream_position)) && + stream_position <= stream_size) { + bytes_available = stream_size-stream_position; + } + return CreateAtomFromStream(stream, bytes_available, atom); +} + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::CreateAtomFromStream ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream, + AP4_LargeSize& bytes_available, + AP4_Atom*& atom) +{ + AP4_Result result; + + // NULL by default + atom = NULL; + + // check that there are enough bytes for at least a header + if (bytes_available < 8) return AP4_ERROR_EOS; + + // remember current stream offset + AP4_Position start; + stream.Tell(start); + + // read atom size + AP4_UI32 size_32; + result = stream.ReadUI32(size_32); + if (AP4_FAILED(result)) { + stream.Seek(start); + return result; + } + AP4_UI64 size = size_32; + + // read atom type + AP4_Atom::Type type; + result = stream.ReadUI32(type); + if (AP4_FAILED(result)) { + stream.Seek(start); + return result; + } + + // handle special size values + bool atom_is_large = false; + bool force_64 = false; + if (size == 0) { + // atom extends to end of file + AP4_LargeSize stream_size = 0; + stream.GetSize(stream_size); + if (stream_size >= start) { + size = stream_size - start; + } + } else if (size == 1) { + // 64-bit size + atom_is_large = true; + if (bytes_available < 16) { + stream.Seek(start); + return AP4_ERROR_INVALID_FORMAT; + } + stream.ReadUI64(size); + if (size <= 0xFFFFFFFF) { + force_64 = true; + } + } + + // check the size + if ((size > 0 && size < 8) || size > bytes_available) { + stream.Seek(start); + return AP4_ERROR_INVALID_FORMAT; + } + + // create the atom + switch (type) { + case AP4_ATOM_TYPE_MOOV: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_MoovAtom::Create(size_32, stream, *this); + break; + + case AP4_ATOM_TYPE_MVHD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_MvhdAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_MFHD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_MfhdAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_TRAK: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_TrakAtom::Create(size_32, stream, *this); + break; + + case AP4_ATOM_TYPE_HDLR: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_HdlrAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_TKHD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_TkhdAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_TFHD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_TfhdAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_TRUN: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_TrunAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_MDHD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_MdhdAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_STSD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_StsdAtom::Create(size_32, stream, *this); + break; + + case AP4_ATOM_TYPE_STSC: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_StscAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_STCO: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_StcoAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_CO64: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_Co64Atom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_STSZ: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_StszAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_STTS: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_SttsAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_CTTS: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_CttsAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_STSS: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_StssAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_IODS: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_IodsAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_ESDS: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_EsdsAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_MP4S: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_Mp4sSampleEntry(size_32, stream, *this); + } + break; + + case AP4_ATOM_TYPE_ENCA: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_EncaSampleEntry(size_32, stream, *this); + } + break; + + case AP4_ATOM_TYPE_ENCV: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_EncvSampleEntry(size_32, stream, *this); + } + break; + + case AP4_ATOM_TYPE_DRMS: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_DrmsSampleEntry(size_32, stream, *this); + } + break; + + case AP4_ATOM_TYPE_DRMI: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_DrmiSampleEntry(size_32, stream, *this); + } + break; + + case AP4_ATOM_TYPE_MP4A: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_Mp4aSampleEntry(size_32, stream, *this); + } + break; + + case AP4_ATOM_TYPE_MP4V: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_Mp4vSampleEntry(size_32, stream, *this); + } + break; + + case AP4_ATOM_TYPE_AVC1: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_Avc1SampleEntry(size_32, stream, *this); + } + break; + + case AP4_ATOM_TYPE_ALAC: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_AudioSampleEntry(AP4_ATOM_TYPE_ALAC, + size_32, + stream, + *this); + } + break; + + case AP4_ATOM_TYPE_AVCC: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_AvccAtom::Create(size_32, stream); + break; + +#if !defined(AP4_CONFIG_MINI_BUILD) + case AP4_ATOM_TYPE_UUID: + atom = new AP4_UuidAtom(size, stream); + break; + + case AP4_ATOM_TYPE_8ID_: + atom = new AP4_NullTerminatedStringAtom(type, size, stream); + break; + + case AP4_ATOM_TYPE_8BDL: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_8bdlAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_DREF: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_DrefAtom::Create(size_32, stream, *this); + break; + + case AP4_ATOM_TYPE_URL: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_UrlAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_ELST: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_ElstAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_VMHD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_VmhdAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_SMHD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_SmhdAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_NMHD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_NmhdAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_HMHD: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_HmhdAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_FRMA: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_FrmaAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_SCHM: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_SchmAtom::Create(size_32, &m_ContextStack, stream); + break; + + case AP4_ATOM_TYPE_FTYP: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_FtypAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_RTP_: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + if (GetContext() == AP4_ATOM_TYPE_STSD) { + atom = new AP4_RtpHintSampleEntry(size_32, stream, *this); + } else { + atom = AP4_RtpAtom::Create(size_32, stream); + } + break; + + case AP4_ATOM_TYPE_TIMS: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_TimsAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_SDP_: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_SdpAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_IKMS: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_IkmsAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_ISFM: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_IsfmAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_ISLT: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_IsltAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_ODHE: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_OdheAtom::Create(size_32, stream, *this); + break; + + case AP4_ATOM_TYPE_OHDR: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_OhdrAtom::Create(size_32, stream, *this); + break; + + case AP4_ATOM_TYPE_ODDA: + atom = AP4_OddaAtom::Create(size, stream); + break; + + case AP4_ATOM_TYPE_ODAF: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_OdafAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_GRPI: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_GrpiAtom::Create(size_32, stream); + break; + + case AP4_ATOM_TYPE_IPRO: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_IproAtom::Create(size_32, stream, *this); + break; + + // track ref types + case AP4_ATOM_TYPE_HINT: + case AP4_ATOM_TYPE_CDSC: + case AP4_ATOM_TYPE_SYNC: + case AP4_ATOM_TYPE_MPOD: + case AP4_ATOM_TYPE_DPND: + case AP4_ATOM_TYPE_IPIR: + case AP4_ATOM_TYPE_ALIS: + case AP4_ATOM_TYPE_CHAP: + if (GetContext() == AP4_ATOM_TYPE_TREF) { + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_TrefTypeAtom::Create(type, size_32, stream); + } + break; + +#endif // AP4_CONFIG_MINI_BUILD + + // container atoms + case AP4_ATOM_TYPE_MOOF: + case AP4_ATOM_TYPE_MVEX: + case AP4_ATOM_TYPE_TRAF: + case AP4_ATOM_TYPE_TREF: + case AP4_ATOM_TYPE_HNTI: + case AP4_ATOM_TYPE_STBL: + case AP4_ATOM_TYPE_MDIA: + case AP4_ATOM_TYPE_DINF: + case AP4_ATOM_TYPE_MINF: + case AP4_ATOM_TYPE_SCHI: + case AP4_ATOM_TYPE_SINF: + case AP4_ATOM_TYPE_UDTA: + case AP4_ATOM_TYPE_ILST: + case AP4_ATOM_TYPE_EDTS: + case AP4_ATOM_TYPE_MDRI: + case AP4_ATOM_TYPE_WAVE: + if (atom_is_large) return AP4_ERROR_INVALID_FORMAT; + atom = AP4_ContainerAtom::Create(type, size, false, force_64, stream, *this); + break; + + // full container atoms + case AP4_ATOM_TYPE_META: + case AP4_ATOM_TYPE_ODRM: + case AP4_ATOM_TYPE_ODKM: + atom = AP4_ContainerAtom::Create(type, size, true, force_64, stream, *this); + break; + + case AP4_ATOM_TYPE_FREE: + case AP4_ATOM_TYPE_WIDE: + case AP4_ATOM_TYPE_MDAT: + // generic atoms + break; + + // ==> Start patch MPC case AP4_ATOM_TYPE_TEXT:
- atom = DNew AP4_TextSampleEntry(size, stream, *this);
+ atom = new AP4_TextSampleEntry(size, stream, *this);
break;
case AP4_ATOM_TYPE_TX3G:
- atom = DNew AP4_Tx3gSampleEntry(size, stream, *this);
+ atom = new AP4_Tx3gSampleEntry(size, stream, *this);
break;
case AP4_ATOM_TYPE_FTAB:
- atom = DNew AP4_FtabAtom(size, stream);
+ atom = new AP4_FtabAtom(size, stream);
break;
case AP4_ATOM_TYPE_CVID:
@@ -388,7 +561,7 @@ AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream, case AP4_ATOM_TYPE_SVQ3:
case AP4_ATOM_TYPE_H263:
case AP4_ATOM_TYPE_S263:
- atom = DNew AP4_VisualSampleEntry(type, size, stream, *this);
+ atom = new AP4_VisualSampleEntry(type, size, stream, *this);
break;
case AP4_ATOM_TYPE_SAMR:
@@ -398,64 +571,139 @@ AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream, case AP4_ATOM_TYPE_QDM2:
case AP4_ATOM_TYPE_TWOS:
case AP4_ATOM_TYPE_SOWT:
- atom = DNew AP4_AudioSampleEntry(type, size, stream, *this);
+ atom = new AP4_AudioSampleEntry(type, size, stream, *this);
break;
case AP4_ATOM_TYPE__AC3: // AC3-in-MP4 from ISO Standard
case AP4_ATOM_TYPE_SAC3: // AC3-in-MP4 from Nero Stuff >.<
- atom = DNew AP4_AC3SampleEntry(size, stream, *this);
- break;
-
- case AP4_ATOM_TYPE_CHPL:
- atom = DNew AP4_ChplAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_DATA:
- atom = DNew AP4_DataAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_DCOM:
- atom = DNew AP4_DcomAtom(size, stream);
- break;
-
- case AP4_ATOM_TYPE_CMVD:
- atom = DNew AP4_CmvdAtom(size, stream, *this);
- break;
-
- default:
-
- if(parent && parent->GetType() == AP4_ATOM_TYPE_STSD && (type & 0xffff0000) == AP4_ATOM_TYPE('m', 's', 0, 0))
- {
- atom = DNew AP4_AudioSampleEntry(type, size, stream, *this);
- }
- else // try all the external type handlers
- {
- atom = NULL;
- AP4_List<TypeHandler>::Item* handler_item = m_TypeHandlers.FirstItem();
- while (handler_item) {
- TypeHandler* handler = handler_item->GetData();
- if (AP4_SUCCEEDED(handler->CreateAtom(type, size, stream, atom))) {
- break;
- }
- handler_item = handler_item->GetNext();
- }
- if (atom == NULL) {
- // no custom handlers, create a generic atom
- atom = DNew AP4_UnknownAtom(type, size, false, stream);
- }
- }
-
- break;
- }
-
- // skip to the end of the atom
- bytes_available -= size;
- result = stream.Seek(start+size);
- if (AP4_FAILED(result)) {
- delete atom;
- atom = NULL;
- }
-
- return result;
-}
-
+ atom = new AP4_AC3SampleEntry(size, stream, *this);
+ break;
+ // <== End patch MPC + + default: + // try all the external type handlers + { + AP4_List<TypeHandler>::Item* handler_item = m_TypeHandlers.FirstItem(); + while (handler_item) { + TypeHandler* handler = handler_item->GetData(); + if (AP4_SUCCEEDED(handler->CreateAtom(type, size_32, stream, GetContext(), atom))) { + break; + } + handler_item = handler_item->GetNext(); + } + + break; + } + } + + // if we failed to create an atom, use a generic version + if (atom == NULL) { + unsigned int payload_offset = 8; + if (atom_is_large) payload_offset += 8; + stream.Seek(start+payload_offset); + atom = new AP4_UnknownAtom(type, size, stream); + } + + // special case: if the atom is poorly encoded and has a 64-bit + // size header but an actual size that fits on 32-bit, adjust the + // object to reflect that. + if (force_64) { + atom->SetSize32(1); + atom->SetSize64(size); + } + + // adjust the available size + bytes_available -= size; + + // skip to the end of the atom + result = stream.Seek(start+size); + if (AP4_FAILED(result)) { + delete atom; + atom = NULL; + return result; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::CreateAtomsFromStream ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomFactory::CreateAtomsFromStream(AP4_ByteStream& stream, + AP4_AtomParent& atoms) +{ + AP4_LargeSize stream_size = 0; + AP4_Position stream_position = 0; + AP4_LargeSize bytes_available = (AP4_LargeSize)(-1); + if (AP4_SUCCEEDED(stream.GetSize(stream_size)) && + stream_size != 0 && + AP4_SUCCEEDED(stream.Tell(stream_position)) && + stream_position <= stream_size) { + bytes_available = stream_size-stream_position; + } + return CreateAtomsFromStream(stream, bytes_available, atoms); +} + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::CreateAtomsFromStream ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomFactory::CreateAtomsFromStream(AP4_ByteStream& stream, + AP4_LargeSize bytes_available, + AP4_AtomParent& atoms) +{ + AP4_Result result; + do { + AP4_Atom* atom = NULL; + result = CreateAtomFromStream(stream, bytes_available, atom); + if (AP4_SUCCEEDED(result) && atom != NULL) { + atoms.AddChild(atom); + } + } while (AP4_SUCCEEDED(result)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::PushContext ++---------------------------------------------------------------------*/ +void +AP4_AtomFactory::PushContext(AP4_Atom::Type context) +{ + m_ContextStack.Append(context); +} + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::PopContext ++---------------------------------------------------------------------*/ +void +AP4_AtomFactory::PopContext() +{ + m_ContextStack.RemoveLast(); +} + +/*---------------------------------------------------------------------- +| AP4_AtomFactory::GetContext ++---------------------------------------------------------------------*/ +AP4_Atom::Type +AP4_AtomFactory::GetContext(AP4_Ordinal depth) +{ + AP4_Ordinal available = m_ContextStack.ItemCount(); + if (depth >= available) return 0; + return m_ContextStack[available-depth-1]; +} + +/*---------------------------------------------------------------------- +| AP4_DefaultAtomFactory::Instance ++---------------------------------------------------------------------*/ +AP4_DefaultAtomFactory AP4_DefaultAtomFactory::Instance; + +/*---------------------------------------------------------------------- +| AP4_DefaultAtomFactory::Instance ++---------------------------------------------------------------------*/ +AP4_DefaultAtomFactory::AP4_DefaultAtomFactory() +{ + // register built-in type handlers + AddTypeHandler(new AP4_MetaDataAtomTypeHandler(this)); +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomFactory.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomFactory.h index f8faf5813..3c7486a7c 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomFactory.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomFactory.h @@ -1,84 +1,103 @@ -/*****************************************************************
-|
-| AP4 - Atom Factory
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_ATOM_FACTORY_H_
-#define _AP4_ATOM_FACTORY_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4Types.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| class references
-+---------------------------------------------------------------------*/
-class AP4_ByteStream;
-
-/*----------------------------------------------------------------------
-| AP4_AtomFactory
-+---------------------------------------------------------------------*/
-class AP4_AtomFactory {
- public:
- // types
- class TypeHandler {
- public:
- virtual ~TypeHandler() {};
- virtual AP4_Result CreateAtom(AP4_Atom::Type type,
- AP4_Size size,
- AP4_ByteStream& stream,
- AP4_Atom*& atom) = 0;
- };
-
- // class members
- static AP4_AtomFactory DefaultFactory;
-
- // constructor
- AP4_AtomFactory() : m_Context(0) {}
-
- // methods
- AP4_Result AddTypeHandler(TypeHandler* handler);
- AP4_Result RemoveTypeHandler(TypeHandler* handler);
- AP4_Result CreateAtomFromStream(AP4_ByteStream& stream,
- AP4_Size& bytes_available,
- AP4_Atom*& atom,
- AP4_Atom* parent);
- AP4_Result CreateAtomFromStream(AP4_ByteStream& stream,
- AP4_Atom*& atom);
-
- // context
- void SetContext(AP4_Atom::Type context) { m_Context = context; }
- AP4_Atom::Type GetContext() const { return m_Context; }
-
-private:
- // members
- AP4_Atom::Type m_Context;
- AP4_List<TypeHandler> m_TypeHandlers;
-};
-
-#endif // _AP4_ATOM_FACTORY_H_
+/***************************************************************** +| +| AP4 - Atom Factory +| +| 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_ATOM_FACTORY_H_ +#define _AP4_ATOM_FACTORY_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" +#include "Ap4Array.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| AP4_AtomFactory ++---------------------------------------------------------------------*/ +class AP4_AtomFactory { + public: + // types + class TypeHandler { + public: + virtual ~TypeHandler() {}; + virtual AP4_Result CreateAtom(AP4_Atom::Type type, + AP4_UI32 size, + AP4_ByteStream& stream, + AP4_Atom::Type context, + AP4_Atom*& atom) = 0; + }; + + // constructor + AP4_AtomFactory() {} + + // destructor + ~AP4_AtomFactory(); + + // methods + AP4_Result AddTypeHandler(TypeHandler* handler); + AP4_Result RemoveTypeHandler(TypeHandler* handler); + AP4_Result CreateAtomFromStream(AP4_ByteStream& stream, + AP4_LargeSize& bytes_available, + AP4_Atom*& atom); + AP4_Result CreateAtomFromStream(AP4_ByteStream& stream, + AP4_Atom*& atom); + AP4_Result CreateAtomsFromStream(AP4_ByteStream& stream, + AP4_AtomParent& atoms); + AP4_Result CreateAtomsFromStream(AP4_ByteStream& stream, + AP4_LargeSize bytes_available, + AP4_AtomParent& atoms); + + // context + void PushContext(AP4_Atom::Type context); + void PopContext(); + AP4_Atom::Type GetContext(AP4_Ordinal depth=0); + +private: + // members + AP4_Array<AP4_Atom::Type> m_ContextStack; + AP4_List<TypeHandler> m_TypeHandlers; +}; + +/*---------------------------------------------------------------------- +| AP4_DefaultAtomFactory ++---------------------------------------------------------------------*/ +class AP4_DefaultAtomFactory : public AP4_AtomFactory { +public: + // class members + static AP4_DefaultAtomFactory Instance; + + // constructor + AP4_DefaultAtomFactory(); +}; + +#endif // _AP4_ATOM_FACTORY_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomSampleTable.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomSampleTable.cpp index c142d0193..66ca1f125 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomSampleTable.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomSampleTable.cpp @@ -1,266 +1,329 @@ -/*****************************************************************
-|
-| AP4 - Atom Based Sample Tables
-|
-| Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| This atom is part of AP4 (MP4 Audio Proatom 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 atom COPYING. If not, write to the
-| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-| 02111-1307, USA.
-|
- ****************************************************************/
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4AtomSampleTable.h"
-#include "Ap4ByteStream.h"
-#include "Ap4StsdAtom.h"
-#include "Ap4StscAtom.h"
-#include "Ap4StcoAtom.h"
-#include "Ap4Co64Atom.h"
-#include "Ap4StszAtom.h"
-#include "Ap4SttsAtom.h"
-#include "Ap4CttsAtom.h"
-#include "Ap4StssAtom.h"
-#include "Ap4Sample.h"
-#include "Ap4SampleEntry.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::AP4_AtomSampleTable
-+---------------------------------------------------------------------*/
-AP4_AtomSampleTable::AP4_AtomSampleTable(AP4_ContainerAtom* stbl,
- AP4_ByteStream& sample_stream) :
- m_SampleStream(sample_stream)
-{
- m_StscAtom = dynamic_cast<AP4_StscAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STSC));
- m_StcoAtom = dynamic_cast<AP4_StcoAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STCO));
- m_Co64Atom = dynamic_cast<AP4_Co64Atom*>(stbl->GetChild(AP4_ATOM_TYPE_CO64));
- m_StszAtom = dynamic_cast<AP4_StszAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STSZ));
- m_CttsAtom = dynamic_cast<AP4_CttsAtom*>(stbl->GetChild(AP4_ATOM_TYPE_CTTS));
- m_SttsAtom = dynamic_cast<AP4_SttsAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STTS));
- m_StssAtom = dynamic_cast<AP4_StssAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STSS));
- m_StsdAtom = dynamic_cast<AP4_StsdAtom*>(stbl->GetChild(AP4_ATOM_TYPE_STSD));
-
- // keep a reference to the sample stream
- m_SampleStream.AddReference();
-
- if(m_StsdAtom && m_StszAtom && m_StscAtom && m_SttsAtom
- && m_StszAtom->m_SampleSize == 1)
- {
- // fix mov files
- for(AP4_List<AP4_Atom>::Item* item = m_StsdAtom->GetChildren().FirstItem();
- item;
- item = item->GetNext())
- {
- AP4_Atom* atom = item->GetData();
-
- if(AP4_AudioSampleEntry* ase = dynamic_cast<AP4_AudioSampleEntry*>(atom))
- {
- AP4_UI32 SamplesPerPacket = ase->GetSamplesPerPacket();
- AP4_UI32 BytesPerFrame = ase->GetBytesPerFrame();
-
- if(SamplesPerPacket > 0 && BytesPerFrame > 0)
- {
- for(int i = 0, j = m_StscAtom->m_Entries.ItemCount(); i < j; i++)
- {
- AP4_StscTableEntry& e = m_StscAtom->m_Entries[i];
- AP4_ASSERT(e.m_SamplesPerChunk % SamplesPerPacket == 0);
- e.m_SamplesPerChunk = e.m_SamplesPerChunk / SamplesPerPacket;
- e.m_FirstSample = (e.m_FirstSample-1) / SamplesPerPacket + 1;
- }
-
- AP4_ASSERT(m_StszAtom->m_SampleCount % SamplesPerPacket == 0);
- m_StszAtom->m_SampleCount = m_StszAtom->m_SampleCount / SamplesPerPacket;
- m_StszAtom->m_SampleSize = BytesPerFrame;
-
- AP4_ASSERT(m_SttsAtom->m_Entries.ItemCount() == 1);
- m_SttsAtom->m_Entries[0].m_SampleCount = m_StszAtom->m_SampleCount;
- m_SttsAtom->m_Entries[0].m_SampleDuration = SamplesPerPacket;
- }
- }
- }
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::~AP4_AtomSampleTable
-+---------------------------------------------------------------------*/
-AP4_AtomSampleTable::~AP4_AtomSampleTable()
-{
- m_SampleStream.Release();
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::GetSample
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomSampleTable::GetSample(AP4_Ordinal index,
- AP4_Sample& sample)
-{
- AP4_Result result;
-
- // MP4 uses 1-based indexes internally, so adjust by one
- index++;
-
- // find out in which chunk this sample is located
- AP4_Ordinal chunk, skip, desc;
- result = m_StscAtom->GetChunkForSample(index, chunk, skip, desc);
- if (AP4_FAILED(result)) return result;
-
- // check that the result is within bounds
- if (skip > index) return AP4_ERROR_INTERNAL;
-
- // get the atom offset for this chunk
- AP4_Offset offset;
- if (m_StcoAtom) result = m_StcoAtom->GetChunkOffset(chunk, offset);
- else if (m_Co64Atom) result = m_Co64Atom->GetChunkOffset(chunk, offset);
- else result = AP4_ERROR_INTERNAL;
- if (AP4_FAILED(result)) return result;
-/*
- // compute the additional offset inside the chunk
- for (unsigned int i = index-skip; i < index; i++) {
- AP4_Size size;
- result = m_StszAtom->GetSampleSize(i, size);
- if (AP4_FAILED(result)) return result;
- offset += size;
- }
-*/
- AP4_Size size;
- result = m_StszAtom->GetSampleSize(index - skip, index, size);
- if (AP4_FAILED(result)) return result;
- offset += size;
-
- // set the description index
- sample.SetDescriptionIndex(desc-1); // adjust for 0-based indexes
-
- // set the dts and cts
- AP4_TimeStamp dts;
- AP4_Duration duration;
- result = m_SttsAtom->GetDts(index, dts, duration);
- if (AP4_FAILED(result)) return result;
- sample.SetDts(dts);
- sample.SetDuration(duration);
- if (m_CttsAtom == NULL) {
- sample.SetCts(dts);
- } else {
- AP4_UI32 cts_offset;
- result = m_CttsAtom->GetCtsOffset(index, cts_offset);
- if (AP4_FAILED(result)) return result;
- sample.SetCts(dts + *((signed long*)&cts_offset)); // HACK: it shouldn't be signed, but such files exist unfortunatelly
- }
-
- // set the size
- AP4_Size sample_size;
- result = m_StszAtom->GetSampleSize(index, sample_size);
- if (AP4_FAILED(result)) return result;
- sample.SetSize(sample_size);
-
- // set the offset
- sample.SetOffset(offset);
-
- // set the data stream
- sample.SetDataStream(m_SampleStream);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::GetSampleCount
-+---------------------------------------------------------------------*/
-AP4_Cardinal
-AP4_AtomSampleTable::GetSampleCount()
-{
- return m_StszAtom ? m_StszAtom->GetSampleCount() : 0;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::GetSampleDescription
-+---------------------------------------------------------------------*/
-AP4_SampleDescription*
-AP4_AtomSampleTable::GetSampleDescription(AP4_Ordinal index)
-{
- return m_StsdAtom ? m_StsdAtom->GetSampleDescription(index) : NULL;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::GetSampleDescriptionCount
-+---------------------------------------------------------------------*/
-AP4_Cardinal
-AP4_AtomSampleTable::GetSampleDescriptionCount()
-{
- return m_StsdAtom ? m_StsdAtom->GetSampleDescriptionCount() : 0;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::GetChunkForSample
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomSampleTable::GetChunkForSample(AP4_Ordinal sample,
- AP4_Ordinal& chunk,
- AP4_Ordinal& skip,
- AP4_Ordinal& sample_description)
-{
- return m_StscAtom ? m_StscAtom->GetChunkForSample(sample, chunk, skip, sample_description) : AP4_FAILURE;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::GetChunkOffset
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomSampleTable::GetChunkOffset(AP4_Ordinal chunk, AP4_Offset& offset)
-{
- return
- m_StcoAtom ? m_StcoAtom->GetChunkOffset(chunk, offset) :
- m_Co64Atom ? m_Co64Atom->GetChunkOffset(chunk, offset) :
- AP4_FAILURE;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::SetChunkOffset
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomSampleTable::SetChunkOffset(AP4_Ordinal chunk, AP4_Offset offset)
-{
- return
- m_StcoAtom ? m_StcoAtom->SetChunkOffset(chunk, offset) :
- m_Co64Atom ? m_Co64Atom->SetChunkOffset(chunk, offset) :
- AP4_FAILURE;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::SetSampleSize
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomSampleTable::SetSampleSize(AP4_Ordinal sample, AP4_Size size)
-{
- return m_StszAtom ? m_StszAtom->SetSampleSize(sample, size) : AP4_FAILURE;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable::GetSample
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AtomSampleTable::GetSampleIndexForTimeStamp(AP4_TimeStamp ts,
- AP4_Ordinal& index)
-{
- return m_SttsAtom ? m_SttsAtom->GetSampleIndexForTimeStamp(ts, index)
- : AP4_FAILURE;
-}
+/***************************************************************** +| +| AP4 - Atom Based Sample Tables +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This atom is part of AP4 (MP4 Audio Proatom 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 atom COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4AtomSampleTable.h" +#include "Ap4ByteStream.h" +#include "Ap4StsdAtom.h" +#include "Ap4StscAtom.h" +#include "Ap4StcoAtom.h" +#include "Ap4Co64Atom.h" +#include "Ap4StszAtom.h" +#include "Ap4SttsAtom.h" +#include "Ap4CttsAtom.h" +#include "Ap4StssAtom.h" +#include "Ap4Sample.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::AP4_AtomSampleTable ++---------------------------------------------------------------------*/ +AP4_AtomSampleTable::AP4_AtomSampleTable(AP4_ContainerAtom* stbl, + AP4_ByteStream& sample_stream) : + m_SampleStream(sample_stream) +{ + m_StscAtom = AP4_DYNAMIC_CAST(AP4_StscAtom, stbl->GetChild(AP4_ATOM_TYPE_STSC)); + m_StcoAtom = AP4_DYNAMIC_CAST(AP4_StcoAtom, stbl->GetChild(AP4_ATOM_TYPE_STCO)); + m_StszAtom = AP4_DYNAMIC_CAST(AP4_StszAtom, stbl->GetChild(AP4_ATOM_TYPE_STSZ)); + m_CttsAtom = AP4_DYNAMIC_CAST(AP4_CttsAtom, stbl->GetChild(AP4_ATOM_TYPE_CTTS)); + m_SttsAtom = AP4_DYNAMIC_CAST(AP4_SttsAtom, stbl->GetChild(AP4_ATOM_TYPE_STTS)); + m_StssAtom = AP4_DYNAMIC_CAST(AP4_StssAtom, stbl->GetChild(AP4_ATOM_TYPE_STSS)); + m_StsdAtom = AP4_DYNAMIC_CAST(AP4_StsdAtom, stbl->GetChild(AP4_ATOM_TYPE_STSD)); + m_Co64Atom = AP4_DYNAMIC_CAST(AP4_Co64Atom, stbl->GetChild(AP4_ATOM_TYPE_CO64)); + + // keep a reference to the sample stream + m_SampleStream.AddReference(); +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::~AP4_AtomSampleTable ++---------------------------------------------------------------------*/ +AP4_AtomSampleTable::~AP4_AtomSampleTable() +{ + m_SampleStream.Release(); +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::GetSample ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomSampleTable::GetSample(AP4_Ordinal index, + AP4_Sample& sample) +{ + AP4_Result result; + + // check that we have a chunk offset table + if (m_StcoAtom == NULL && m_Co64Atom == NULL) { + return AP4_ERROR_INVALID_FORMAT; + } + + // MP4 uses 1-based indexes internally, so adjust by one + index++; + + // find out in which chunk this sample is located + AP4_Ordinal chunk, skip, desc; + result = m_StscAtom->GetChunkForSample(index, chunk, skip, desc); + if (AP4_FAILED(result)) return result; + + // check that the result is within bounds + if (skip > index) return AP4_ERROR_INTERNAL; + + // get the atom offset for this chunk + AP4_UI64 offset; + if (m_StcoAtom) { + AP4_UI32 offset_32; + result = m_StcoAtom->GetChunkOffset(chunk, offset_32); + offset = offset_32; + } else { + result = m_Co64Atom->GetChunkOffset(chunk, offset); + } + if (AP4_FAILED(result)) return result; + + // compute the additional offset inside the chunk + for (unsigned int i = index-skip; i < index; i++) { + AP4_Size size; + result = m_StszAtom->GetSampleSize(i, size); + if (AP4_FAILED(result)) return result; + offset += size; + } + + // set the description index + sample.SetDescriptionIndex(desc-1); // adjust for 0-based indexes + + // set the dts and cts + AP4_UI32 cts_offset = 0; + AP4_UI64 dts = 0; + AP4_UI32 duration = 0; + result = m_SttsAtom->GetDts(index, dts, &duration); + if (AP4_FAILED(result)) return result; + sample.SetDuration(duration); + sample.SetDts(dts); + if (m_CttsAtom == NULL) { + sample.SetCts(dts); + } else { + result = m_CttsAtom->GetCtsOffset(index, cts_offset); + if (AP4_FAILED(result)) return result; + sample.SetCts(dts + cts_offset); + } + + // set the size + AP4_Size sample_size; + result = m_StszAtom->GetSampleSize(index, sample_size); + if (AP4_FAILED(result)) return result; + sample.SetSize(sample_size); + + // set the sync flag + if (m_StssAtom == NULL) { + sample.SetSync(true); + } else { + sample.SetSync(m_StssAtom->IsSampleSync(index)); + } + + // set the offset + sample.SetOffset(offset); + + // set the data stream + sample.SetDataStream(m_SampleStream); + + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::GetSampleCount ++---------------------------------------------------------------------*/ +AP4_Cardinal +AP4_AtomSampleTable::GetSampleCount() +{ + return m_StszAtom ? m_StszAtom->GetSampleCount() : 0; +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::GetSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_AtomSampleTable::GetSampleDescription(AP4_Ordinal index) +{ + return m_StsdAtom ? m_StsdAtom->GetSampleDescription(index) : NULL; +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::GetSampleDescriptionCount ++---------------------------------------------------------------------*/ +AP4_Cardinal +AP4_AtomSampleTable::GetSampleDescriptionCount() +{ + return m_StsdAtom ? m_StsdAtom->GetSampleDescriptionCount() : 0; +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::GetSampleChunkPosition ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomSampleTable::GetSampleChunkPosition(AP4_Ordinal sample_index, + AP4_Ordinal& chunk_index, + AP4_Ordinal& position_in_chunk) +{ + // default values + chunk_index = 0; + position_in_chunk = 0; + + AP4_Ordinal sample_description_index; + return GetChunkForSample(sample_index, + chunk_index, + position_in_chunk, + sample_description_index); +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::GetChunkForSample ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomSampleTable::GetChunkForSample(AP4_Ordinal sample_index, + AP4_Ordinal& chunk_index, + AP4_Ordinal& position_in_chunk, + AP4_Ordinal& sample_description_index) +{ + // default values + chunk_index = 0; + position_in_chunk = 0; + sample_description_index = 0; + + // check that we an stsc atom + if (m_StscAtom == NULL) return AP4_ERROR_INVALID_STATE; + + // get the chunk info from the stsc atom + AP4_Ordinal chunk = 0; + AP4_Result result = m_StscAtom->GetChunkForSample(sample_index+1, // the atom API is 1-based + chunk, + position_in_chunk, + sample_description_index); + if (AP4_FAILED(result)) return result; + if (chunk == 0) return AP4_ERROR_INTERNAL; + + // the atom sample and chunk indexes are 1-based, so we need to translate + chunk_index = chunk-1; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::GetChunkOffset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomSampleTable::GetChunkOffset(AP4_Ordinal chunk_index, + AP4_Position& offset) +{ + if (m_StcoAtom) { + AP4_UI32 offset_32; + AP4_Result result = m_StcoAtom->GetChunkOffset(chunk_index+1, offset_32); + if (AP4_SUCCEEDED(result)) { + offset = offset_32; + } else { + offset = 0; + } + return result; + } else if (m_Co64Atom) { + return m_Co64Atom->GetChunkOffset(chunk_index+1, offset); + } else { + offset = 0; + return AP4_FAILURE; + } +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::SetChunkOffset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomSampleTable::SetChunkOffset(AP4_Ordinal chunk_index, + AP4_Position offset) +{ + if (m_StcoAtom) { + if ((offset >> 32) != 0) return AP4_ERROR_OUT_OF_RANGE; + return m_StcoAtom->SetChunkOffset(chunk_index+1, (AP4_UI32)offset); + } else if (m_Co64Atom) { + return m_Co64Atom->SetChunkOffset(chunk_index+1, offset); + } else { + return AP4_FAILURE; + } +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::SetSampleSize ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomSampleTable::SetSampleSize(AP4_Ordinal sample_index, AP4_Size size) +{ + return m_StszAtom ? m_StszAtom->SetSampleSize(sample_index+1, size) : AP4_FAILURE; +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::GetSampleIndexForTimeStamp ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomSampleTable::GetSampleIndexForTimeStamp(AP4_UI64 ts, + AP4_Ordinal& sample_index) +{ + return m_SttsAtom ? m_SttsAtom->GetSampleIndexForTimeStamp(ts, sample_index) + : AP4_FAILURE; +} + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable::GetNearestSyncSampleIndex ++---------------------------------------------------------------------*/ +AP4_Ordinal +AP4_AtomSampleTable::GetNearestSyncSampleIndex(AP4_Ordinal sample_index, bool before) +{ + // if we don't have an stss table, all samples match + if (m_StssAtom == NULL) return sample_index; + + sample_index += 1; // the table is 1-based + AP4_Cardinal entry_count = m_StssAtom->GetEntries().ItemCount(); + if (before) { + AP4_Ordinal cursor = 0; + for (unsigned int i=0; i<entry_count; i++) { + if (m_StssAtom->GetEntries()[i] >= sample_index) return cursor; + if (m_StssAtom->GetEntries()[i]) cursor = m_StssAtom->GetEntries()[i]-1; + } + + // not found? + return cursor; + } else { + for (unsigned int i=0; i<entry_count; i++) { + if (m_StssAtom->GetEntries()[i] >= sample_index) { + return m_StssAtom->GetEntries()[i]?m_StssAtom->GetEntries()[i]-1:sample_index-1; + } + } + + // not found? + return GetSampleCount(); + } +} + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomSampleTable.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomSampleTable.h index 68a71d13b..9e99bad98 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomSampleTable.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AtomSampleTable.h @@ -1,91 +1,96 @@ -/*****************************************************************
-|
-| AP4 - Atom Based Sample Table
-|
-| Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| This atom is part of AP4 (MP4 Audio Proatom 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 atom COPYING. If not, write to the
-| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-| 02111-1307, USA.
-|
- ****************************************************************/
-
-#ifndef _AP4_ATOM_SAMPLE_TABLE_H_
-#define _AP4_ATOM_SAMPLE_TABLE_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4Types.h"
-#include "Ap4SampleTable.h"
-
-/*----------------------------------------------------------------------
-| forward declarations
-+---------------------------------------------------------------------*/
-class AP4_Atom;
-class AP4_ByteStream;
-class AP4_StscAtom;
-class AP4_StcoAtom;
-class AP4_Co64Atom;
-class AP4_StszAtom;
-class AP4_SttsAtom;
-class AP4_CttsAtom;
-class AP4_StssAtom;
-class AP4_StsdAtom;
-
-/*----------------------------------------------------------------------
-| AP4_AtomSampleTable
-+---------------------------------------------------------------------*/
-class AP4_AtomSampleTable : public AP4_SampleTable
-{
- public:
- // methods
- AP4_AtomSampleTable(AP4_ContainerAtom* stbl_atom,
- AP4_ByteStream& sample_stream);
- virtual ~AP4_AtomSampleTable();
-
- // AP4_SampleTable methods
- virtual AP4_Result GetSample(AP4_Ordinal index, AP4_Sample& sample);
- virtual AP4_Cardinal GetSampleCount();
- virtual AP4_SampleDescription* GetSampleDescription(AP4_Ordinal index);
- virtual AP4_Cardinal GetSampleDescriptionCount();
- virtual AP4_Result GetChunkForSample(AP4_Ordinal sample,
- AP4_Ordinal& chunk,
- AP4_Ordinal& skip,
- AP4_Ordinal& sample_description);
- virtual AP4_Result GetChunkOffset(AP4_Ordinal chunk, AP4_Offset& offset);
- virtual AP4_Result SetChunkOffset(AP4_Ordinal chunk, AP4_Offset offset);
- virtual AP4_Result SetSampleSize(AP4_Ordinal sample, AP4_Size size);
- virtual AP4_Result GetSampleIndexForTimeStamp(AP4_TimeStamp ts,
- AP4_Ordinal& index);
-
-private:
- // members
- AP4_ByteStream& m_SampleStream;
- AP4_StscAtom* m_StscAtom;
- AP4_StcoAtom* m_StcoAtom;
- AP4_Co64Atom* m_Co64Atom;
- AP4_StszAtom* m_StszAtom;
- AP4_SttsAtom* m_SttsAtom;
- AP4_CttsAtom* m_CttsAtom;
- AP4_StsdAtom* m_StsdAtom;
- AP4_StssAtom* m_StssAtom;
-};
-
-#endif // _AP4_ATOM_SAMPLE_TABLE_H_
+/***************************************************************** +| +| AP4 - Atom Based Sample Table +| +| Copyright 2002-2008 Axiomatic Systems, LLC +| +| +| This atom is part of AP4 (MP4 Audio Proatom 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 atom COPYING. If not, write to the +| Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +| 02111-1307, USA. +| + ****************************************************************/ + +#ifndef _AP4_ATOM_SAMPLE_TABLE_H_ +#define _AP4_ATOM_SAMPLE_TABLE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4SampleTable.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class AP4_Atom; +class AP4_ByteStream; +class AP4_StscAtom; +class AP4_StcoAtom; +class AP4_StszAtom; +class AP4_SttsAtom; +class AP4_CttsAtom; +class AP4_StssAtom; +class AP4_StsdAtom; +class AP4_Co64Atom; + +/*---------------------------------------------------------------------- +| AP4_AtomSampleTable ++---------------------------------------------------------------------*/ +class AP4_AtomSampleTable : public AP4_SampleTable +{ + public: + // methods + AP4_AtomSampleTable(AP4_ContainerAtom* stbl_atom, + AP4_ByteStream& sample_stream); + virtual ~AP4_AtomSampleTable(); + + // AP4_SampleTable methods + virtual AP4_Result GetSample(AP4_Ordinal sample_index, AP4_Sample& sample); + virtual AP4_Cardinal GetSampleCount(); + virtual AP4_SampleDescription* GetSampleDescription(AP4_Ordinal sd_index); + virtual AP4_Cardinal GetSampleDescriptionCount(); + virtual AP4_Result GetSampleChunkPosition(AP4_Ordinal sample_index, + AP4_Ordinal& chunk_index, + AP4_Ordinal& position_in_chunk); + virtual AP4_Result GetSampleIndexForTimeStamp(AP4_UI64 ts, AP4_Ordinal& sample_index); + virtual AP4_Ordinal GetNearestSyncSampleIndex(AP4_Ordinal index, bool before=true); + + // local methods + virtual AP4_Result GetChunkForSample(AP4_Ordinal sample_index, + AP4_Ordinal& chunk_index, + AP4_Ordinal& position_in_chunk, + AP4_Ordinal& sample_description_index); + virtual AP4_Result GetChunkOffset(AP4_Ordinal chunk_index, AP4_Position& offset); + virtual AP4_Result SetChunkOffset(AP4_Ordinal chunk_index, AP4_Position offset); + virtual AP4_Result SetSampleSize(AP4_Ordinal sample_index, AP4_Size size); + +private: + // members + AP4_ByteStream& m_SampleStream; + AP4_StscAtom* m_StscAtom; + AP4_StcoAtom* m_StcoAtom; + AP4_StszAtom* m_StszAtom; + AP4_SttsAtom* m_SttsAtom; + AP4_CttsAtom* m_CttsAtom; + AP4_StsdAtom* m_StsdAtom; + AP4_StssAtom* m_StssAtom; + AP4_Co64Atom* m_Co64Atom; +}; + +#endif // _AP4_ATOM_SAMPLE_TABLE_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AvcCAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AvcCAtom.cpp index 52738ea75..c21f64e7e 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AvcCAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AvcCAtom.cpp @@ -1,46 +1,226 @@ -/*****************************************************************
-|
-| AP4 - avcC Atom
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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 "Ap4AvcCAtom.h"
-
-/*----------------------------------------------------------------------
-| AP4_AvcCAtom::AP4_AvcCAtom
-+---------------------------------------------------------------------*/
-
-AP4_AvcCAtom::AP4_AvcCAtom(AP4_Size size,
- AP4_ByteStream& stream)
- : AP4_Atom(AP4_ATOM_TYPE_AVCC)
-{
- size -= AP4_ATOM_HEADER_SIZE;
- m_DecoderInfo.SetDataSize(size);
- stream.Read(m_DecoderInfo.UseData(), size);
-}
+/***************************************************************** +| +| AP4 - avcC 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 "Ap4AvccAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" +#include "Ap4Types.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_AvccAtom) + +/*---------------------------------------------------------------------- +| AP4_AvccAtom::GetProfileName ++---------------------------------------------------------------------*/ +const char* +AP4_AvccAtom::GetProfileName(AP4_UI08 profile) +{ + switch (profile) { + case AP4_AVC_PROFILE_BASELINE: return "Baseline"; + case AP4_AVC_PROFILE_MAIN: return "Main"; + case AP4_AVC_PROFILE_EXTENDED: return "Extended"; + case AP4_AVC_PROFILE_HIGH: return "High"; + case AP4_AVC_PROFILE_HIGH_10: return "High 10"; + case AP4_AVC_PROFILE_HIGH_422: return "High 4:2:2"; + case AP4_AVC_PROFILE_HIGH_444: return "High 4:4:4"; + } + + return NULL; +} + +/*---------------------------------------------------------------------- +| AP4_AvccAtom::AP4_AvccAtom ++---------------------------------------------------------------------*/ +AP4_AvccAtom::AP4_AvccAtom() : + AP4_Atom(AP4_ATOM_TYPE_AVCC, AP4_ATOM_HEADER_SIZE+7), + m_ConfigurationVersion(0), + m_Profile(0), + m_Level(0), + m_ProfileCompatibility(0), + m_NaluLengthSize(0) +{ +} + +/*---------------------------------------------------------------------- +| AP4_AvccAtom::AP4_AvccAtom ++---------------------------------------------------------------------*/ +AP4_AvccAtom::AP4_AvccAtom(const AP4_AvccAtom& other) : + AP4_Atom(AP4_ATOM_TYPE_AVCC, other.m_Size32), + m_ConfigurationVersion (other.m_ConfigurationVersion), + m_Profile(other.m_Profile), + m_Level(other.m_Level), + m_ProfileCompatibility(other.m_ProfileCompatibility), + m_NaluLengthSize(other.m_NaluLengthSize), + m_RawBytes(other.m_RawBytes) +{ + // deep copy of the parameters + unsigned int i = 0; + for (i=0; i<other.m_SequenceParameters.ItemCount(); i++) { + m_SequenceParameters.Append(other.m_SequenceParameters[i]); + } + for (i=0; i<other.m_PictureParameters.ItemCount(); i++) { + m_PictureParameters.Append(other.m_PictureParameters[i]); + } +} + +/*---------------------------------------------------------------------- +| AP4_AvccAtom::AP4_AvccAtom ++---------------------------------------------------------------------*/ +AP4_AvccAtom::AP4_AvccAtom(AP4_UI32 size, AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_AVCC, size) +{ + // make a copy of our configuration bytes + AP4_Position start_pos; + stream.Tell(start_pos); + m_RawBytes.SetDataSize(size); + stream.Read(m_RawBytes.UseData(), size); + stream.Seek(start_pos); + + stream.ReadUI08(m_ConfigurationVersion); + stream.ReadUI08(m_Profile); + stream.ReadUI08(m_ProfileCompatibility); + stream.ReadUI08(m_Level); + AP4_UI08 length_size_minus_one; + stream.ReadUI08(length_size_minus_one); + m_NaluLengthSize = 1+(length_size_minus_one&3); + AP4_UI08 num_seq_params; + stream.ReadUI08(num_seq_params); + num_seq_params &= 31; + m_SequenceParameters.EnsureCapacity(num_seq_params); + for (unsigned int i=0; i<num_seq_params; i++) { + m_SequenceParameters.Append(AP4_DataBuffer()); + AP4_UI16 param_length; + stream.ReadUI16(param_length); + m_SequenceParameters[i].SetDataSize(param_length); + stream.Read(m_SequenceParameters[i].UseData(), param_length); + } + AP4_UI08 num_pic_params; + stream.ReadUI08(num_pic_params); + for (unsigned int i=0; i<num_pic_params; i++) { + m_PictureParameters.Append(AP4_DataBuffer()); + AP4_UI16 param_length; + stream.ReadUI16(param_length); + m_PictureParameters[i].SetDataSize(param_length); + stream.Read(m_PictureParameters[i].UseData(), param_length); + } +} + + +/*---------------------------------------------------------------------- +| AP4_AvccAtom::AP4_AvccAtom ++---------------------------------------------------------------------*/ +AP4_AvccAtom::AP4_AvccAtom(AP4_UI08 config_version, + AP4_UI08 profile, + AP4_UI08 level, + AP4_UI08 profile_compatibility, + AP4_UI08 length_size, + const AP4_Array<AP4_DataBuffer>& sequence_parameters, + const AP4_Array<AP4_DataBuffer>& picture_parameters) : + AP4_Atom(AP4_ATOM_TYPE_AVCC, AP4_ATOM_HEADER_SIZE+7), + m_ConfigurationVersion(config_version), + m_Profile(profile), + m_Level(level), + m_ProfileCompatibility(profile_compatibility), + m_NaluLengthSize(length_size) +{ + // deep copy of the parameters + unsigned int i = 0; + for (i=0; i<sequence_parameters.ItemCount(); i++) { + m_SequenceParameters.Append(sequence_parameters[i]); + m_Size32 += 2+sequence_parameters[i].GetDataSize(); + } + for (i=0; i<picture_parameters.ItemCount(); i++) { + m_PictureParameters.Append(picture_parameters[i]); + m_Size32 += 2+picture_parameters[i].GetDataSize(); + } +} + + +/*---------------------------------------------------------------------- +| AP4_AvccAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AvccAtom::WriteFields(AP4_ByteStream& stream) +{ + stream.WriteUI08(m_ConfigurationVersion); + stream.WriteUI08(m_Profile); + stream.WriteUI08(m_ProfileCompatibility); + stream.WriteUI08(m_Level); + AP4_UI08 length_size_minus_one = 0xFC; + if (m_NaluLengthSize >= 1 && m_NaluLengthSize <= 4) { + length_size_minus_one |= m_NaluLengthSize-1; + } + stream.WriteUI08(length_size_minus_one); + m_NaluLengthSize = 1+(length_size_minus_one&3); + AP4_UI08 num_seq_params = (AP4_UI08)(m_SequenceParameters.ItemCount()&0x31); + stream.WriteUI08(0xE0 | num_seq_params); + for (unsigned int i=0; i<num_seq_params; i++) { + AP4_UI16 param_length = (AP4_UI16)m_SequenceParameters[i].GetDataSize(); + stream.WriteUI16(param_length); + stream.Write(m_SequenceParameters[i].GetData(), param_length); + } + AP4_UI08 num_pic_params = (AP4_UI08)m_PictureParameters.ItemCount(); + stream.WriteUI08(num_pic_params); + for (unsigned int i=0; i<num_pic_params; i++) { + AP4_UI16 param_length = (AP4_UI16)m_PictureParameters[i].GetDataSize(); + stream.WriteUI16(param_length); + stream.Write(m_PictureParameters[i].GetData(), param_length); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_AvccAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AvccAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("Configuration Version", m_ConfigurationVersion); + const char* profile_name = GetProfileName(m_Profile); + if (profile_name) { + inspector.AddField("Profile", profile_name); + } else { + inspector.AddField("Profile", m_Profile); + } + inspector.AddField("Profile Compatibility", m_ProfileCompatibility, AP4_AtomInspector::HINT_HEX); + inspector.AddField("Level", m_Level); + inspector.AddField("NALU Length Size", m_NaluLengthSize); + for (unsigned int i=0; i<m_SequenceParameters.ItemCount(); i++) { + inspector.AddField("Sequence Parameter", m_SequenceParameters[i].GetData(), m_SequenceParameters[i].GetDataSize()); + } + for (unsigned int i=0; i<m_SequenceParameters.ItemCount(); i++) { + inspector.AddField("Picture Parameter", m_PictureParameters[i].GetData(), m_PictureParameters[i].GetDataSize()); + } + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AvcCAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AvcCAtom.h index 00acf7e9e..c143f4363 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AvcCAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4AvcCAtom.h @@ -1,57 +1,104 @@ -/*****************************************************************
-|
-| AP4 - avcC Atom
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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_AVCC_ATOM_H_
-#define _AP4_AVCC_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4Atom.h"
-#include "Ap4Types.h"
-#include "Ap4Array.h"
-#include "Ap4DataBuffer.h"
-
-/*----------------------------------------------------------------------
-| AP4_AvcCAtom
-+---------------------------------------------------------------------*/
-class AP4_AvcCAtom : public AP4_Atom
-{
-public:
- AP4_AvcCAtom(AP4_Size size,
- AP4_ByteStream& stream);
-
- AP4_Result WriteFields(AP4_ByteStream& stream) { return AP4_FAILURE; }
-
- const AP4_DataBuffer* GetDecoderInfo() const { return &m_DecoderInfo; }
-
-private:
- AP4_DataBuffer m_DecoderInfo;
-};
-
-#endif // _AP4_AVCC_ATOM_H_
+/***************************************************************** +| +| AP4 - avcC 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_AVCC_ATOM_H_ +#define _AP4_AVCC_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" +#include "Ap4Array.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI08 AP4_AVC_PROFILE_BASELINE = 66; +const AP4_UI08 AP4_AVC_PROFILE_MAIN = 77; +const AP4_UI08 AP4_AVC_PROFILE_EXTENDED = 88; +const AP4_UI08 AP4_AVC_PROFILE_HIGH = 100; +const AP4_UI08 AP4_AVC_PROFILE_HIGH_10 = 110; +const AP4_UI08 AP4_AVC_PROFILE_HIGH_422 = 122; +const AP4_UI08 AP4_AVC_PROFILE_HIGH_444 = 144; + + +/*---------------------------------------------------------------------- +| AP4_AvccAtom ++---------------------------------------------------------------------*/ +class AP4_AvccAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_AvccAtom, AP4_Atom) + + // class methods + static AP4_AvccAtom* Create(AP4_Size size, AP4_ByteStream& stream) { + return new AP4_AvccAtom(size, stream); + } + static const char* GetProfileName(AP4_UI08 profile); + + // constructors + AP4_AvccAtom(); + AP4_AvccAtom(AP4_UI08 config_version, + AP4_UI08 profile, + AP4_UI08 level, + AP4_UI08 profile_compatibility, + AP4_UI08 length_size, + const AP4_Array<AP4_DataBuffer>& sequence_parameters, + const AP4_Array<AP4_DataBuffer>& picture_parameters); + AP4_AvccAtom(const AP4_AvccAtom& other); // copy construtor + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // accessors + AP4_UI08 GetConfigurationVersion() const { return m_ConfigurationVersion; } + AP4_UI08 GetProfile() const { return m_Profile; } + AP4_UI08 GetLevel() const { return m_Level; } + AP4_UI08 GetProfileCompatibility() const { return m_ProfileCompatibility; } + AP4_UI08 GetNaluLengthSize() const { return m_NaluLengthSize; } + AP4_Array<AP4_DataBuffer>& GetSequenceParameters() { return m_SequenceParameters; } + AP4_Array<AP4_DataBuffer>& GetPictureParameters() { return m_PictureParameters; } + const AP4_DataBuffer& GetRawBytes() const { return m_RawBytes; } + +private: + // methods + AP4_AvccAtom(AP4_UI32 size, AP4_ByteStream& stream); + + // members + AP4_UI08 m_ConfigurationVersion; + AP4_UI08 m_Profile; + AP4_UI08 m_Level; + AP4_UI08 m_ProfileCompatibility; + AP4_UI08 m_NaluLengthSize; + AP4_Array<AP4_DataBuffer> m_SequenceParameters; + AP4_Array<AP4_DataBuffer> m_PictureParameters; + AP4_DataBuffer m_RawBytes; +}; + +#endif // _AP4_AVCC_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ByteStream.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ByteStream.cpp index 0385c3a7b..e6848f2cf 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ByteStream.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ByteStream.cpp @@ -1,573 +1,676 @@ -/*****************************************************************
-|
-| AP4 - Byte Stream support
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4ByteStream.h"
-#include "Ap4Utils.h"
-#include "Ap4Debug.h"
-
-/*----------------------------------------------------------------------
-| constants
-+---------------------------------------------------------------------*/
-const int AP4_BYTE_STREAM_COPY_BUFFER_SIZE = 4096;
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::WriteString
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::WriteString(const char* buffer)
-{
- AP4_Size string_length = static_cast<AP4_Size>(strlen(buffer));
-
- // shortcut
- if ((buffer == NULL) || (string_length == 0)) return AP4_SUCCESS;
-
- // write the string
- return Write((const void*)buffer, string_length);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::WriteUI64
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::WriteUI64(AP4_UI64 value)
-{
- unsigned char buffer[8];
-
- // convert value to bytes
- AP4_BytesFromUInt64BE(buffer, value);
-
- // write bytes to the stream
- return Write((void*)buffer, 8);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::WriteUI32
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::WriteUI32(AP4_UI32 value)
-{
- unsigned char buffer[4];
-
- // convert value to bytes
- AP4_BytesFromUInt32BE(buffer, value);
-
- // write bytes to the stream
- return Write((void*)buffer, 4);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::WriteUI24
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::WriteUI24(AP4_UI32 value)
-{
- unsigned char buffer[3];
-
- // convert value to bytes
- AP4_BytesFromUInt24BE(buffer, value);
-
- // write bytes to the stream
- return Write((void*)buffer, 3);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::WriteUI16
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::WriteUI16(AP4_UI16 value)
-{
- unsigned char buffer[2];
-
- // convert value to bytes
- AP4_BytesFromUInt16BE(buffer, value);
-
- // write bytes to the stream
- return Write((void*)buffer, 2);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::WriteUI08
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::WriteUI08(AP4_UI08 value)
-{
- return Write((void*)&value, 1);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::ReadUI64
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::ReadUI64(AP4_UI64& value)
-{
- unsigned char buffer[8];
-
- // read bytes from the stream
- AP4_Result result;
- result = Read((void*)buffer, 8);
- if (AP4_FAILED(result)) {
- value = 0;
- return result;
- }
-
- // convert bytes to value
- value = AP4_BytesToUInt64BE(buffer);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::ReadUI32
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::ReadUI32(AP4_UI32& value)
-{
- unsigned char buffer[4];
-
- // read bytes from the stream
- AP4_Result result;
- result = Read((void*)buffer, 4);
- if (AP4_FAILED(result)) {
- value = 0;
- return result;
- }
-
- // convert bytes to value
- value = AP4_BytesToUInt32BE(buffer);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::ReadUI24
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::ReadUI24(AP4_UI32& value)
-{
- unsigned char buffer[3];
-
- // read bytes from the stream
- AP4_Result result;
- result = Read((void*)buffer, 3);
- if (AP4_FAILED(result)) {
- value = 0;
- return result;
- }
-
- // convert bytes to value
- value = AP4_BytesToUInt24BE(buffer);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::ReadUI16
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::ReadUI16(AP4_UI16& value)
-{
- unsigned char buffer[2];
-
- // read bytes from the stream
- AP4_Result result;
- result = Read((void*)buffer, 2);
- if (AP4_FAILED(result)) {
- value = 0;
- return result;
- }
-
- // convert bytes to value
- value = AP4_BytesToUInt16BE(buffer);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::ReadUI08
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::ReadUI08(AP4_UI08& value)
-{
- unsigned char buffer[1];
-
- // read bytes from the stream
- AP4_Result result;
- result = Read((void*)buffer, 1);
- if (AP4_FAILED(result)) {
- value = 0;
- return result;
- }
-
- // convert bytes to value
- value = buffer[0];
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::ReadString
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::ReadString(char* buffer, AP4_Size size)
-{
- if (buffer == NULL || size == 0) {
- return AP4_ERROR_INVALID_PARAMETERS;
- }
-
- AP4_Size bytes_read = 0;
- while (bytes_read < size-1) {
- AP4_Result result;
- result = Read(&buffer[bytes_read], 1, NULL);
- if (AP4_FAILED(result)) {
- buffer[bytes_read] = '\0';
- return result;
- }
- if (buffer[bytes_read] == '\0') {
- // end of string
- return AP4_SUCCESS;
- }
- bytes_read++;
- }
-
- // the string was not null terminated, terminate it
- buffer[size-1] = '\0';
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream::CopyTo
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ByteStream::CopyTo(AP4_ByteStream& stream, AP4_Size size)
-{
- unsigned char buffer[AP4_BYTE_STREAM_COPY_BUFFER_SIZE];
- while (size) {
- AP4_Size bytes_read;
- AP4_Size bytes_to_read;
- AP4_Result result;
-
- // decide how much to read
- if (size >= sizeof(buffer)) {
- bytes_to_read = sizeof(buffer);
- } else {
- bytes_to_read = size;
- }
-
- // read up to one buffer full
- result = Read(buffer, bytes_to_read, &bytes_read);
- if (AP4_FAILED(result)) return result;
-
- // copy to destination
- if (bytes_read != 0) {
- result = stream.Write(buffer, bytes_read);
- if (AP4_FAILED(result)) return result;
- }
-
- // update the size
- size -= bytes_read;
- }
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SubStream::AP4_SubStream
-+---------------------------------------------------------------------*/
-AP4_SubStream::AP4_SubStream(AP4_ByteStream& container,
- AP4_Offset offset,
- AP4_Size size) :
- m_Container(container),
- m_Offset(offset),
- m_Size(size),
- m_Position(0),
- m_ReferenceCount(1)
-{
- m_Container.AddReference();
-}
-
-/*----------------------------------------------------------------------
-| AP4_SubStream::~AP4_SubStream
-+---------------------------------------------------------------------*/
-AP4_SubStream::~AP4_SubStream()
-{
- m_Container.Release();
-}
-
-/*----------------------------------------------------------------------
-| AP4_SubStream::Read
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SubStream::Read(void* buffer,
- AP4_Size bytes_to_read,
- AP4_Size* bytes_read)
-{
- // default values
- if (bytes_read) *bytes_read = 0;
-
- // shortcut
- if (bytes_to_read == 0) {
- return AP4_SUCCESS;
- }
-
- // clamp to range
- if (m_Position+bytes_to_read > m_Size) {
- bytes_to_read = m_Size - m_Position;
- }
-
- // check for end of substream
- if (bytes_to_read == 0) {
- return AP4_ERROR_EOS;
- }
-
- // seek inside container
- //AP4_Result result;
- //result = m_Container.Seek(m_Offset+m_Position);
- //if (AP4_FAILED(result)) {
- // return result;
- //}
-
- // read from the container
- AP4_Size local_bytes_read;
- AP4_Result result = m_Container.Read(buffer, bytes_to_read, &local_bytes_read);
- if (bytes_read) *bytes_read = local_bytes_read;
- if (AP4_SUCCEEDED(result)) {
- m_Position += local_bytes_read;
- }
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SubStream::Write
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SubStream::Write(const void* buffer,
- AP4_Size bytes_to_write,
- AP4_Size* bytes_written)
-{
- // default values
- if (bytes_written) *bytes_written = 0;
-
- // shortcut
- if (bytes_to_write == 0) {
- return AP4_SUCCESS;
- }
-
- // clamp to range
- if (m_Position+bytes_to_write > m_Size) {
- bytes_to_write = m_Size - m_Position;
- }
-
- // check for en of substream
- if (bytes_to_write == 0) {
- return AP4_ERROR_EOS;
- }
-
- // seek inside container
- //AP4_Result result;
- //result = m_Container.Seek(m_Offset+m_Position);
- //if (AP4_FAILED(result)) return result;
-
- // write to container
- AP4_Size local_bytes_written;
- AP4_Result result = m_Container.Write(buffer, bytes_to_write, &local_bytes_written);
- if (bytes_written) *bytes_written = local_bytes_written;
- if (AP4_SUCCEEDED(result)) {
- m_Position += local_bytes_written;
- }
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SubStream::Seek
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SubStream::Seek(AP4_Offset offset)
-{
- if (offset > m_Size) return AP4_FAILURE;
- AP4_Result result;
- result = m_Container.Seek(m_Offset+offset);
- if (AP4_SUCCEEDED(result)) {
- m_Position = offset;
- }
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SubStream::AddReference
-+---------------------------------------------------------------------*/
-void
-AP4_SubStream::AddReference()
-{
- m_ReferenceCount++;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SubStream::Release
-+---------------------------------------------------------------------*/
-void
-AP4_SubStream::Release()
-{
- if (--m_ReferenceCount == 0) {
- delete this;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_MemoryByteStream::AP4_MemoryByteStream
-+---------------------------------------------------------------------*/
-AP4_MemoryByteStream::AP4_MemoryByteStream(AP4_Size size) :
- m_BufferIsLocal(true),
- m_Size(size),
- m_Position(0),
- m_ReferenceCount(1)
-{
- m_Buffer = DNew AP4_UI08[size];
-}
-
-/*----------------------------------------------------------------------
-| AP4_MemoryByteStream::AP4_MemoryByteStream
-+---------------------------------------------------------------------*/
-AP4_MemoryByteStream::AP4_MemoryByteStream(AP4_UI08* buffer, AP4_Size size) :
- m_BufferIsLocal(false),
- m_Buffer(buffer),
- m_Size(size),
- m_Position(0),
- m_ReferenceCount(1)
-{}
-
-/*----------------------------------------------------------------------
-| AP4_MemoryByteStream::~AP4_MemoryByteStream
-+---------------------------------------------------------------------*/
-AP4_MemoryByteStream::~AP4_MemoryByteStream()
-{
- if (m_BufferIsLocal) delete[] m_Buffer;
-}
-
-/*----------------------------------------------------------------------
-| AP4_MemoryByteStream::Read
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_MemoryByteStream::Read(void* buffer,
- AP4_Size bytes_to_read,
- AP4_Size* bytes_read)
-{
- // default values
- if (bytes_read) *bytes_read = 0;
-
- // shortcut
- if (bytes_to_read == 0) {
- return AP4_SUCCESS;
- }
-
- // clamp to range
- if (m_Position+bytes_to_read > m_Size) {
- bytes_to_read = m_Size - m_Position;
- }
-
- // check for end of stream
- if (bytes_to_read == 0) {
- return AP4_ERROR_EOS;
- }
-
- // read from the memory
- memcpy(buffer, &m_Buffer[m_Position], bytes_to_read);
- m_Position += bytes_to_read;
-
- if (bytes_read) *bytes_read = bytes_to_read;
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_MemoryByteStream::Write
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_MemoryByteStream::Write(const void* buffer,
- AP4_Size bytes_to_write,
- AP4_Size* bytes_written)
-{
- // default values
- if (bytes_written) *bytes_written = 0;
-
- // shortcut
- if (bytes_to_write == 0) {
- return AP4_SUCCESS;
- }
-
- // clamp to range
- if (m_Position+bytes_to_write > m_Size) {
- bytes_to_write = m_Size - m_Position;
- }
-
- // check for en of stream
- if (bytes_to_write == 0) {
- return AP4_ERROR_EOS;
- }
-
- // write to memory
- memcpy(&m_Buffer[m_Position], buffer, bytes_to_write);
- m_Position += bytes_to_write;
-
- if (bytes_written) *bytes_written = bytes_to_write;
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_MemoryByteStream::Seek
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_MemoryByteStream::Seek(AP4_Offset offset)
-{
- if (offset > m_Size) return AP4_FAILURE;
- m_Position = offset;
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_MemoryByteStream::AddReference
-+---------------------------------------------------------------------*/
-void
-AP4_MemoryByteStream::AddReference()
-{
- m_ReferenceCount++;
-}
-
-/*----------------------------------------------------------------------
-| AP4_MemoryByteStream::Release
-+---------------------------------------------------------------------*/
-void
-AP4_MemoryByteStream::Release()
-{
- if (--m_ReferenceCount == 0) {
- delete this;
- }
-}
+/***************************************************************** +| +| AP4 - Byte 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 "Ap4ByteStream.h" +#include "Ap4Utils.h" +#include "Ap4Debug.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int AP4_BYTE_STREAM_COPY_BUFFER_SIZE = 65536; +const int AP4_MEMORY_BYTE_STREAM_MAX_SIZE = 0x4000000; // 64 megs + +/*---------------------------------------------------------------------- +| AP4_ByteStream::Read ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::Read(void* buffer, AP4_Size bytes_to_read) +{ + // shortcut + if (bytes_to_read == 0) return AP4_SUCCESS; + + // read until failure + AP4_Size bytes_read; + while (bytes_to_read) { + AP4_Result result = ReadPartial(buffer, bytes_to_read, bytes_read); + if (AP4_FAILED(result)) return result; + if (bytes_read == 0) return AP4_ERROR_INTERNAL; + AP4_ASSERT(bytes_read <= bytes_to_read); + bytes_to_read -= bytes_read; + buffer = (void*)(((AP4_Byte*)buffer)+bytes_read); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Stream::Write ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::Write(const void* buffer, AP4_Size bytes_to_write) +{ + // shortcut + if (bytes_to_write == 0) return AP4_SUCCESS; + + // write until failure + AP4_Size bytes_written; + while (bytes_to_write) { + AP4_Result result = WritePartial(buffer, bytes_to_write, bytes_written); + if (AP4_FAILED(result)) return result; + if (bytes_written == 0) return AP4_ERROR_INTERNAL; + AP4_ASSERT(bytes_written <= bytes_to_write); + bytes_to_write -= bytes_written; + buffer = (const void*)(((const AP4_Byte*)buffer)+bytes_written); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::WriteString ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::WriteString(const char* buffer) +{ + AP4_Size string_length = static_cast<AP4_Size>(strlen(buffer)); + + // shortcut + if ((buffer == NULL) || (string_length == 0)) return AP4_SUCCESS; + + // write the string + return Write((const void*)buffer, string_length); +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::WriteDouble ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::WriteDouble(double value) +{ + unsigned char buffer[8]; + + // convert value to bytes + AP4_BytesFromDoubleBE(buffer, value); + + // write bytes to the stream + return Write((void*)buffer, 8); +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::WriteUI64 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::WriteUI64(AP4_UI64 value) +{ + unsigned char buffer[8]; + + // convert value to bytes + AP4_BytesFromUInt64BE(buffer, value); + + // write bytes to the stream + return Write((void*)buffer, 8); +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::WriteUI32 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::WriteUI32(AP4_UI32 value) +{ + unsigned char buffer[4]; + + // convert value to bytes + AP4_BytesFromUInt32BE(buffer, value); + + // write bytes to the stream + return Write((void*)buffer, 4); +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::WriteUI24 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::WriteUI24(AP4_UI32 value) +{ + unsigned char buffer[3]; + + // convert value to bytes + AP4_BytesFromUInt24BE(buffer, value); + + // write bytes to the stream + return Write((void*)buffer, 3); +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::WriteUI16 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::WriteUI16(AP4_UI16 value) +{ + unsigned char buffer[2]; + + // convert value to bytes + AP4_BytesFromUInt16BE(buffer, value); + + // write bytes to the stream + return Write((void*)buffer, 2); +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::WriteUI08 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::WriteUI08(AP4_UI08 value) +{ + return Write((void*)&value, 1); +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::ReadUI64 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::ReadUI64(AP4_UI64& value) +{ + unsigned char buffer[8]; + + // read bytes from the stream + AP4_Result result; + result = Read((void*)buffer, 8); + if (AP4_FAILED(result)) { + value = 0; + return result; + } + + // convert bytes to value + value = AP4_BytesToUInt64BE(buffer); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::ReadDouble ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::ReadDouble(double& value) +{ + unsigned char buffer[8]; + + // read bytes from the stream + AP4_Result result; + result = Read((void*)buffer, 8); + if (AP4_FAILED(result)) { + value = 0; + return result; + } + + // convert bytes to value + value = AP4_BytesToDoubleBE(buffer); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::ReadUI32 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::ReadUI32(AP4_UI32& value) +{ + unsigned char buffer[4]; + + // read bytes from the stream + AP4_Result result; + result = Read((void*)buffer, 4); + if (AP4_FAILED(result)) { + value = 0; + return result; + } + + // convert bytes to value + value = AP4_BytesToUInt32BE(buffer); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::ReadUI24 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::ReadUI24(AP4_UI32& value) +{ + unsigned char buffer[3]; + + // read bytes from the stream + AP4_Result result; + result = Read((void*)buffer, 3); + if (AP4_FAILED(result)) { + value = 0; + return result; + } + + // convert bytes to value + value = AP4_BytesToUInt24BE(buffer); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::ReadUI16 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::ReadUI16(AP4_UI16& value) +{ + unsigned char buffer[2]; + + // read bytes from the stream + AP4_Result result; + result = Read((void*)buffer, 2); + if (AP4_FAILED(result)) { + value = 0; + return result; + } + + // convert bytes to value + value = AP4_BytesToUInt16BE(buffer); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::ReadUI08 ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::ReadUI08(AP4_UI08& value) +{ + unsigned char buffer[1]; + + // read bytes from the stream + AP4_Result result; + result = Read((void*)buffer, 1); + if (AP4_FAILED(result)) { + value = 0; + return result; + } + + // convert bytes to value + value = buffer[0]; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::ReadString ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::ReadString(char* buffer, AP4_Size size) +{ + if (buffer == NULL || size == 0) { + return AP4_ERROR_INVALID_PARAMETERS; + } + + AP4_Size bytes_read = 0; + while (bytes_read < size-1) { + AP4_Result result; + result = Read(&buffer[bytes_read], 1); + if (AP4_FAILED(result)) { + buffer[bytes_read] = '\0'; + return result; + } + if (buffer[bytes_read] == '\0') { + // end of string + return AP4_SUCCESS; + } + bytes_read++; + } + + // the string was not null terminated, terminate it + buffer[size-1] = '\0'; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ByteStream::CopyTo ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ByteStream::CopyTo(AP4_ByteStream& stream, AP4_LargeSize size) +{ + unsigned char buffer[AP4_BYTE_STREAM_COPY_BUFFER_SIZE]; + while (size) { + AP4_Size bytes_read; + AP4_Size bytes_to_read; + AP4_Result result; + + // decide how much to read + if (size >= sizeof(buffer)) { + bytes_to_read = sizeof(buffer); + } else { + bytes_to_read = (AP4_Size)size; + } + + // read up to one buffer full + result = ReadPartial(buffer, bytes_to_read, bytes_read); + if (AP4_FAILED(result)) return result; + + // copy to destination + if (bytes_read != 0) { + result = stream.Write(buffer, bytes_read); + if (AP4_FAILED(result)) return result; + } + + // update the size + size -= bytes_read; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_SubStream::AP4_SubStream ++---------------------------------------------------------------------*/ +AP4_SubStream::AP4_SubStream(AP4_ByteStream& container, + AP4_Position offset, + AP4_LargeSize size) : + m_Container(container), + m_Offset(offset), + m_Size(size), + m_Position(0), + m_ReferenceCount(1) +{ + m_Container.AddReference(); +} + +/*---------------------------------------------------------------------- +| AP4_SubStream::~AP4_SubStream ++---------------------------------------------------------------------*/ +AP4_SubStream::~AP4_SubStream() +{ + m_Container.Release(); +} + +/*---------------------------------------------------------------------- +| AP4_SubStream::ReadPartial ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SubStream::ReadPartial(void* buffer, + AP4_Size bytes_to_read, + AP4_Size& bytes_read) +{ + // default values + bytes_read = 0; + + // shortcut + if (bytes_to_read == 0) { + return AP4_SUCCESS; + } + + // clamp to range + if (m_Position+bytes_to_read > m_Size) { + bytes_to_read = (AP4_Size)(m_Size - m_Position); + } + + // check for end of substream + if (bytes_to_read == 0) { + return AP4_ERROR_EOS; + } + + // seek inside container + AP4_Result result; + result = m_Container.Seek(m_Offset+m_Position); + if (AP4_FAILED(result)) { + return result; + } + + // read from the container + result = m_Container.ReadPartial(buffer, bytes_to_read, bytes_read); + if (AP4_SUCCEEDED(result)) { + m_Position += bytes_read; + } + return result; +} + +/*---------------------------------------------------------------------- +| AP4_SubStream::WritePartial ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SubStream::WritePartial(const void* buffer, + AP4_Size bytes_to_write, + AP4_Size& bytes_written) +{ + // default values + bytes_written = 0; + + // shortcut + if (bytes_to_write == 0) { + return AP4_SUCCESS; + } + + // clamp to range + if (m_Position+bytes_to_write > m_Size) { + bytes_to_write = (AP4_Size)(m_Size - m_Position); + } + + // check for en of substream + if (bytes_to_write == 0) { + return AP4_ERROR_EOS; + } + + // seek inside container + AP4_Result result; + result = m_Container.Seek(m_Offset+m_Position); + if (AP4_FAILED(result)) return result; + + // write to container + result = m_Container.WritePartial(buffer, bytes_to_write, bytes_written); + if (AP4_SUCCEEDED(result)) { + m_Position += bytes_written; + } + return result; +} + +/*---------------------------------------------------------------------- +| AP4_SubStream::Seek ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SubStream::Seek(AP4_Position position) +{ + if (position == m_Position) return AP4_SUCCESS; + if (position > m_Size) return AP4_FAILURE; + m_Position = position; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_SubStream::AddReference ++---------------------------------------------------------------------*/ +void +AP4_SubStream::AddReference() +{ + m_ReferenceCount++; +} + +/*---------------------------------------------------------------------- +| AP4_SubStream::Release ++---------------------------------------------------------------------*/ +void +AP4_SubStream::Release() +{ + if (--m_ReferenceCount == 0) { + delete this; + } +} + +/*---------------------------------------------------------------------- +| AP4_MemoryByteStream::AP4_MemoryByteStream ++---------------------------------------------------------------------*/ +AP4_MemoryByteStream::AP4_MemoryByteStream(AP4_Size size) : + m_BufferIsLocal(true), + m_Position(0), + m_ReferenceCount(1) +{ + m_Buffer = new AP4_DataBuffer(size); + AP4_SetMemory(m_Buffer->UseData(), 0, size); + m_Buffer->SetDataSize(size); +} + +/*---------------------------------------------------------------------- +| AP4_MemoryByteStream::AP4_MemoryByteStream ++---------------------------------------------------------------------*/ +AP4_MemoryByteStream::AP4_MemoryByteStream(const AP4_UI08* buffer, AP4_Size size) : + m_BufferIsLocal(true), + m_Position(0), + m_ReferenceCount(1) +{ + m_Buffer = new AP4_DataBuffer(buffer, size); +} + +/*---------------------------------------------------------------------- + | AP4_MemoryByteStream::AP4_MemoryByteStream + +---------------------------------------------------------------------*/ +AP4_MemoryByteStream::AP4_MemoryByteStream(AP4_DataBuffer& data_buffer) : + m_BufferIsLocal(false), + m_Position(0), + m_ReferenceCount(1) +{ + m_Buffer = &data_buffer; +} + +/*---------------------------------------------------------------------- + | AP4_MemoryByteStream::~AP4_MemoryByteStream + +---------------------------------------------------------------------*/ +AP4_MemoryByteStream::~AP4_MemoryByteStream() +{ + if (m_BufferIsLocal) { + delete m_Buffer; + } +} + +/*---------------------------------------------------------------------- +| AP4_MemoryByteStream::ReadPartial ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MemoryByteStream::ReadPartial(void* buffer, + AP4_Size bytes_to_read, + AP4_Size& bytes_read) +{ + // default values + bytes_read = 0; + + // shortcut + if (bytes_to_read == 0) { + return AP4_SUCCESS; + } + + // clamp to range + if (m_Position+bytes_to_read > m_Buffer->GetDataSize()) { + bytes_to_read = (AP4_Size)(m_Buffer->GetDataSize() - m_Position); + } + + // check for end of stream + if (bytes_to_read == 0) { + return AP4_ERROR_EOS; + } + + // read from the memory + AP4_CopyMemory(buffer, m_Buffer->GetData()+m_Position, bytes_to_read); + m_Position += bytes_to_read; + + bytes_read = bytes_to_read; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MemoryByteStream::WritePartial ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MemoryByteStream::WritePartial(const void* buffer, + AP4_Size bytes_to_write, + AP4_Size& bytes_written) +{ + // default values + bytes_written = 0; + + // shortcut + if (bytes_to_write == 0) { + return AP4_SUCCESS; + } + + // check that we don't exceed the max + if (m_Position+bytes_to_write > (AP4_Position)AP4_MEMORY_BYTE_STREAM_MAX_SIZE) { + return AP4_ERROR_OUT_OF_RANGE; + } + + // reserve space in the buffer + AP4_Result result = m_Buffer->Reserve((AP4_Size)(m_Position+bytes_to_write)); + if (AP4_SUCCEEDED(result)) { + m_Buffer->SetDataSize((AP4_Size)(m_Position+bytes_to_write)); + } else { + // failed to reserve, most likely caused by a buffer that has + // external storage + if (m_Position+bytes_to_write > m_Buffer->GetDataSize()) { + bytes_to_write = (AP4_Size)(m_Buffer->GetDataSize() - m_Position); + } + } + + // check for en of stream + if (bytes_to_write == 0) { + return AP4_ERROR_EOS; + } + + // write to memory + AP4_CopyMemory((void*)(m_Buffer->UseData()+m_Position), buffer, bytes_to_write); + m_Position += bytes_to_write; + + bytes_written = bytes_to_write; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MemoryByteStream::Seek ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MemoryByteStream::Seek(AP4_Position position) +{ + if (position > m_Buffer->GetDataSize()) return AP4_FAILURE; + m_Position = position; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MemoryByteStream::AddReference ++---------------------------------------------------------------------*/ +void +AP4_MemoryByteStream::AddReference() +{ + m_ReferenceCount++; +} + +/*---------------------------------------------------------------------- +| AP4_MemoryByteStream::Release ++---------------------------------------------------------------------*/ +void +AP4_MemoryByteStream::Release() +{ + if (--m_ReferenceCount == 0) { + delete this; + } +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ByteStream.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ByteStream.h index 2e0e99deb..1592f146b 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ByteStream.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ByteStream.h @@ -1,154 +1,164 @@ -/*****************************************************************
-|
-| AP4 - ByteStream Interface
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_BYTE_STREAM_H_
-#define _AP4_BYTE_STREAM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4Types.h"
-#include "Ap4Interfaces.h"
-#include "Ap4Results.h"
-
-/*----------------------------------------------------------------------
-| AP4_ByteStream
-+---------------------------------------------------------------------*/
-class AP4_ByteStream : public AP4_Referenceable
-{
- public:
- // methods
- virtual AP4_Result Read(void* buffer,
- AP4_Size bytes_to_read,
- AP4_Size* bytes_read = 0) = 0;
- virtual AP4_Result ReadUI64(AP4_UI64& value);
- virtual AP4_Result ReadUI32(AP4_UI32& value);
- virtual AP4_Result ReadUI24(AP4_UI32& value);
- virtual AP4_Result ReadUI16(AP4_UI16& value);
- virtual AP4_Result ReadUI08(AP4_UI08& value);
- virtual AP4_Result ReadString(char* buffer, AP4_Size size);
- virtual AP4_Result Write(const void* buffer,
- AP4_Size bytes_to_write,
- AP4_Size* bytes_written = 0) = 0;
- virtual AP4_Result WriteString(const char* stringBuffer);
- virtual AP4_Result WriteUI64(AP4_UI64 value);
- virtual AP4_Result WriteUI32(AP4_UI32 value);
- virtual AP4_Result WriteUI24(AP4_UI32 value);
- virtual AP4_Result WriteUI16(AP4_UI16 value);
- virtual AP4_Result WriteUI08(AP4_UI08 value);
- virtual AP4_Result Seek(AP4_Offset offset) = 0;
- virtual AP4_Result Tell(AP4_Offset& offset) = 0;
- virtual AP4_Result GetSize(AP4_Size& size) = 0;
- virtual AP4_Result CopyTo(AP4_ByteStream& stream, AP4_Size size);
-};
-
-/*----------------------------------------------------------------------
-| AP4_SubStream
-+---------------------------------------------------------------------*/
-class AP4_SubStream : public AP4_ByteStream
-{
- public:
- AP4_SubStream(AP4_ByteStream& container, AP4_Offset offset, AP4_Size size);
-
- // AP4_ByteStream methods
- AP4_Result Read(void* buffer,
- AP4_Size bytes_to_read,
- AP4_Size* bytes_read = 0);
- AP4_Result Write(const void* buffer,
- AP4_Size bytes_to_write,
- AP4_Size* bytes_written = 0);
- AP4_Result Seek(AP4_Offset offset);
- AP4_Result Tell(AP4_Offset& offset) {
- offset = m_Position;
- return AP4_SUCCESS;
- }
- AP4_Result GetSize(AP4_Size& size) {
- size = m_Size;
- return AP4_SUCCESS;
- }
-
- // AP4_Referenceable methods
- void AddReference();
- void Release();
-
- protected:
- virtual ~AP4_SubStream();
-
- private:
- AP4_ByteStream& m_Container;
- AP4_Offset m_Offset;
- AP4_Size m_Size;
- AP4_Offset m_Position;
- AP4_Cardinal m_ReferenceCount;
-};
-
-/*----------------------------------------------------------------------
-| AP4_MemoryByteStream
-+---------------------------------------------------------------------*/
-class AP4_MemoryByteStream : public AP4_ByteStream
-{
-public:
- AP4_MemoryByteStream(AP4_Size size);
- AP4_MemoryByteStream(AP4_UI08* buffer, AP4_Size size);
-
- // AP4_ByteStream methods
- AP4_Result Read(void* buffer,
- AP4_Size bytes_to_read,
- AP4_Size* bytes_read = 0);
- AP4_Result Write(const void* buffer,
- AP4_Size bytes_to_write,
- AP4_Size* bytes_written = 0);
- AP4_Result Seek(AP4_Offset offset);
- AP4_Result Tell(AP4_Offset& offset) {
- offset = m_Position;
- return AP4_SUCCESS;
- }
- AP4_Result GetSize(AP4_Size& size) {
- size = m_Size;
- return AP4_SUCCESS;
- }
-
- // AP4_Referenceable methods
- void AddReference();
- void Release();
-
- // methods
- AP4_UI08* GetBuffer() { return m_Buffer; }
-
-protected:
- virtual ~AP4_MemoryByteStream();
-
-private:
- bool m_BufferIsLocal;
- AP4_UI08* m_Buffer;
- AP4_Size m_Size;
- AP4_Offset m_Position;
- AP4_Cardinal m_ReferenceCount;
-};
-
-#endif // _AP4_BYTE_STREAM_H_
+/***************************************************************** +| +| AP4 - ByteStream Interface +| +| 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_BYTE_STREAM_H_ +#define _AP4_BYTE_STREAM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Interfaces.h" +#include "Ap4Results.h" +#include "Ap4DataBuffer.h" + +/*---------------------------------------------------------------------- +| AP4_ByteStream ++---------------------------------------------------------------------*/ +class AP4_ByteStream : public AP4_Referenceable +{ + public: + // methods + virtual AP4_Result ReadPartial(void* buffer, + AP4_Size bytes_to_read, + AP4_Size& bytes_read) = 0; + AP4_Result Read(void* buffer, AP4_Size bytes_to_read); + AP4_Result ReadDouble(double& value); + AP4_Result ReadUI64(AP4_UI64& value); + AP4_Result ReadUI32(AP4_UI32& value); + AP4_Result ReadUI24(AP4_UI32& value); + AP4_Result ReadUI16(AP4_UI16& value); + AP4_Result ReadUI08(AP4_UI08& value); + AP4_Result ReadString(char* buffer, AP4_Size size); + virtual AP4_Result WritePartial(const void* buffer, + AP4_Size bytes_to_write, + AP4_Size& bytes_written) = 0; + AP4_Result Write(const void* buffer, AP4_Size bytes_to_write); + AP4_Result WriteString(const char* string_buffer); + AP4_Result WriteDouble(double value); + AP4_Result WriteUI64(AP4_UI64 value); + AP4_Result WriteUI32(AP4_UI32 value); + AP4_Result WriteUI24(AP4_UI32 value); + AP4_Result WriteUI16(AP4_UI16 value); + AP4_Result WriteUI08(AP4_UI08 value); + virtual AP4_Result Seek(AP4_Position position) = 0; + virtual AP4_Result Tell(AP4_Position& position) = 0; + virtual AP4_Result GetSize(AP4_LargeSize& size) = 0; + virtual AP4_Result CopyTo(AP4_ByteStream& stream, AP4_LargeSize size); + virtual AP4_Result Flush() { return AP4_SUCCESS; } +}; + +/*---------------------------------------------------------------------- +| AP4_SubStream ++---------------------------------------------------------------------*/ +class AP4_SubStream : public AP4_ByteStream +{ + public: + AP4_SubStream(AP4_ByteStream& container, + AP4_Position position, + AP4_LargeSize size); + + // AP4_ByteStream methods + AP4_Result ReadPartial(void* buffer, + AP4_Size bytes_to_read, + AP4_Size& bytes_read); + AP4_Result WritePartial(const void* buffer, + AP4_Size bytes_to_write, + AP4_Size& bytes_written); + AP4_Result Seek(AP4_Position position); + AP4_Result Tell(AP4_Position& position) { + position = m_Position; + return AP4_SUCCESS; + } + AP4_Result GetSize(AP4_LargeSize& size) { + size = m_Size; + return AP4_SUCCESS; + } + + // AP4_Referenceable methods + void AddReference(); + void Release(); + + protected: + virtual ~AP4_SubStream(); + + private: + AP4_ByteStream& m_Container; + AP4_Position m_Offset; + AP4_LargeSize m_Size; + AP4_Position m_Position; + AP4_Cardinal m_ReferenceCount; +}; + +/*---------------------------------------------------------------------- +| AP4_MemoryByteStream ++---------------------------------------------------------------------*/ +class AP4_MemoryByteStream : public AP4_ByteStream +{ +public: + AP4_MemoryByteStream(AP4_Size size = 0); // filled with zeros + AP4_MemoryByteStream(const AP4_UI08* buffer, AP4_Size size); + AP4_MemoryByteStream(AP4_DataBuffer& data_buffer); // data is read/written from/to supplied buffer + + // AP4_ByteStream methods + AP4_Result ReadPartial(void* buffer, + AP4_Size bytes_to_read, + AP4_Size& bytes_read); + AP4_Result WritePartial(const void* buffer, + AP4_Size bytes_to_write, + AP4_Size& bytes_written); + AP4_Result Seek(AP4_Position position); + AP4_Result Tell(AP4_Position& position) { + position = m_Position; + return AP4_SUCCESS; + } + AP4_Result GetSize(AP4_LargeSize& size) { + size = m_Buffer->GetDataSize(); + return AP4_SUCCESS; + } + + // AP4_Referenceable methods + void AddReference(); + void Release(); + + // methods + const AP4_UI08* GetData() { return m_Buffer->GetData(); } + AP4_UI08* UseData() { return m_Buffer->UseData(); } + AP4_Size GetDataSize() { return m_Buffer->GetDataSize(); } + +protected: + virtual ~AP4_MemoryByteStream(); + +private: + AP4_DataBuffer* m_Buffer; + bool m_BufferIsLocal; + AP4_Position m_Position; + AP4_Cardinal m_ReferenceCount; +}; + +#endif // _AP4_BYTE_STREAM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ChplAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ChplAtom.cpp index fca8b5795..2c5c195a3 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ChplAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ChplAtom.cpp @@ -36,9 +36,9 @@ | AP4_ChplAtom::AP4_ChplAtom
+---------------------------------------------------------------------*/
-AP4_ChplAtom::AP4_ChplAtom(AP4_Size size,
+AP4_ChplAtom::AP4_ChplAtom(AP4_UI32 size,
AP4_ByteStream& stream)
- : AP4_Atom(AP4_ATOM_TYPE_CHPL, size, true, stream)
+ : AP4_Atom(AP4_ATOM_TYPE_CHPL, size)
{
size -= AP4_FULL_ATOM_HEADER_SIZE;
diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ChplAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ChplAtom.h index 7e6ba9b82..d1fa4327b 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ChplAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ChplAtom.h @@ -43,7 +43,7 @@ class AP4_ChplAtom : public AP4_Atom
{
public:
- AP4_ChplAtom(AP4_Size size,
+ AP4_ChplAtom(AP4_UI32 size,
AP4_ByteStream& stream);
AP4_Result WriteFields(AP4_ByteStream& stream) { return AP4_FAILURE; }
diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CmvdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CmvdAtom.cpp deleted file mode 100644 index 83e683617..000000000 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CmvdAtom.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/*****************************************************************
-|
-| AP4 - cmvd Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4CmvdAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4ContainerAtom.h"
-
-/*----------------------------------------------------------------------
-| AP4_CmvdAtom::AP4_CmvdAtom
-+---------------------------------------------------------------------*/
-AP4_CmvdAtom::AP4_CmvdAtom(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_ContainerAtom(AP4_ATOM_TYPE_CMVD, size, false, stream)
-{
- size -= AP4_ATOM_HEADER_SIZE;
-
- stream.ReadUI32(m_MovieResourceSize);
-
- size -= 4;
-
- m_Data.SetDataSize(size);
- stream.Read(m_Data.UseData(), size);
-
-/*
- // read children
- AP4_Size bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-4;
- while (entry_count--) {
- AP4_Atom* atom;
- while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream,
- bytes_available,
- atom,
- this))) {
- m_Children.Add(atom);
- }
- }
-*/
-}
diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Co64Atom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Co64Atom.cpp index 9c3214826..3dea98337 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Co64Atom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Co64Atom.cpp @@ -1,153 +1,178 @@ -/*****************************************************************
-|
-| AP4 - co64 Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4Co64Atom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_Co64Atom::AP4_Co64Atom
-+---------------------------------------------------------------------*/
-AP4_Co64Atom::AP4_Co64Atom(AP4_UI64* entries, AP4_UI32 entry_count) :
-AP4_Atom(AP4_ATOM_TYPE_CO64,
- AP4_FULL_ATOM_HEADER_SIZE+4+entry_count*8,
- true),
- m_Entries(DNew AP4_UI64[entry_count]),
- m_EntryCount(entry_count)
-{
- memcpy(m_Entries, entries, m_EntryCount*8);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Co64Atom::AP4_Co64Atom
-+---------------------------------------------------------------------*/
-AP4_Co64Atom::AP4_Co64Atom(AP4_Size size, AP4_ByteStream& stream) :
- AP4_Atom(AP4_ATOM_TYPE_CO64, size, true, stream)
-{
- stream.ReadUI32(m_EntryCount);
- if (m_EntryCount > (size-AP4_FULL_ATOM_HEADER_SIZE-4)/8) {
- m_EntryCount = (size-AP4_FULL_ATOM_HEADER_SIZE-4)/8;
- }
- m_Entries = DNew AP4_UI64[m_EntryCount];
- for (AP4_Ordinal i=0; i<m_EntryCount; i++) {
- stream.ReadUI64(m_Entries[i]);
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_Co64Atom::~AP4_Co64Atom
-+---------------------------------------------------------------------*/
-AP4_Co64Atom::~AP4_Co64Atom()
-{
- delete[] m_Entries;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Co64Atom::GetChunkOffset
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Co64Atom::GetChunkOffset(AP4_Ordinal chunk, AP4_Offset& chunk_offset)
-{
- // check the bounds
- if (chunk > m_EntryCount || chunk == 0) {
- return AP4_ERROR_OUT_OF_RANGE;
- }
-
- // FIXME!!!
-
- // get the chunk offset
- chunk_offset = m_Entries[chunk - 1]; // m_Entries is zero index based
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Co64Atom::SetChunkOffset
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Co64Atom::SetChunkOffset(AP4_Ordinal chunk, AP4_Offset chunk_offset)
-{
- // check the bounds
- if (chunk > m_EntryCount || chunk == 0) {
- return AP4_ERROR_OUT_OF_RANGE;
- }
-
- // get the chunk offset
- m_Entries[chunk - 1] = chunk_offset; // m_Entries is zero index based
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Co64Atom::AdjustChunkOffsets
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Co64Atom::AdjustChunkOffsets(AP4_Offset offset)
-{
- for (AP4_Ordinal i=0; i<m_EntryCount; i++) {
- m_Entries[i] += offset;
- }
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Co64Atom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Co64Atom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // entry count
- result = stream.WriteUI32(m_EntryCount);
- if (AP4_FAILED(result)) return result;
-
- // entries
- for (AP4_Ordinal i=0; i<m_EntryCount; i++) {
- result = stream.WriteUI64(m_Entries[i]);
- if (AP4_FAILED(result)) return result;
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Co64Atom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Co64Atom::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("entry_count", m_EntryCount);
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - co64 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 "Ap4Co64Atom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_Co64Atom) + +/*---------------------------------------------------------------------- +| AP4_Co64Atom::Create ++---------------------------------------------------------------------*/ +AP4_Co64Atom* +AP4_Co64Atom::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_Co64Atom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_Co64Atom::AP4_Co64Atom ++---------------------------------------------------------------------*/ +AP4_Co64Atom::AP4_Co64Atom(AP4_UI64* entries, AP4_UI32 entry_count) : +AP4_Atom(AP4_ATOM_TYPE_CO64, + AP4_FULL_ATOM_HEADER_SIZE+4+entry_count*8, + 0, 0), + m_Entries(new AP4_UI64[entry_count]), + m_EntryCount(entry_count) +{ + AP4_CopyMemory(m_Entries, entries, m_EntryCount*8); +} + +/*---------------------------------------------------------------------- +| AP4_Co64Atom::AP4_Co64Atom ++---------------------------------------------------------------------*/ +AP4_Co64Atom::AP4_Co64Atom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_CO64, size, version, flags) +{ + stream.ReadUI32(m_EntryCount); + if (m_EntryCount > (size-AP4_FULL_ATOM_HEADER_SIZE-4)/8) { + m_EntryCount = (size-AP4_FULL_ATOM_HEADER_SIZE-4)/8; + } + m_Entries = new AP4_UI64[m_EntryCount]; + for (AP4_Ordinal i=0; i<m_EntryCount; i++) { + stream.ReadUI64(m_Entries[i]); + } +} + +/*---------------------------------------------------------------------- +| AP4_Co64Atom::~AP4_Co64Atom ++---------------------------------------------------------------------*/ +AP4_Co64Atom::~AP4_Co64Atom() +{ + delete[] m_Entries; +} + +/*---------------------------------------------------------------------- +| AP4_Co64Atom::GetChunkOffset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Co64Atom::GetChunkOffset(AP4_Ordinal chunk, AP4_UI64& chunk_offset) +{ + // check the bounds + if (chunk > m_EntryCount || chunk == 0) { + return AP4_ERROR_OUT_OF_RANGE; + } + + // get the chunk offset + chunk_offset = m_Entries[chunk - 1]; // m_Entries is zero index based + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Co64Atom::SetChunkOffset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Co64Atom::SetChunkOffset(AP4_Ordinal chunk, AP4_UI64 chunk_offset) +{ + // check the bounds + if (chunk > m_EntryCount || chunk == 0) { + return AP4_ERROR_OUT_OF_RANGE; + } + + // get the chunk offset + m_Entries[chunk - 1] = chunk_offset; // m_Entries is zero index based + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Co64Atom::AdjustChunkOffsets ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Co64Atom::AdjustChunkOffsets(AP4_SI64 delta) +{ + for (AP4_Ordinal i=0; i<m_EntryCount; i++) { + m_Entries[i] += delta; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Co64Atom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Co64Atom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // entry count + result = stream.WriteUI32(m_EntryCount); + if (AP4_FAILED(result)) return result; + + // entries + for (AP4_Ordinal i=0; i<m_EntryCount; i++) { + result = stream.WriteUI64(m_Entries[i]); + if (AP4_FAILED(result)) return result; + } + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_Co64Atom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Co64Atom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("entry_count", m_EntryCount); + if (inspector.GetVerbosity() >= 1) { + char header[32]; + for (AP4_Ordinal i=0; i<m_EntryCount; i++) { + AP4_FormatString(header, sizeof(header), "entry %8d", i); + inspector.AddField(header, m_Entries[i]); + } + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Co64Atom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Co64Atom.h index aa0c6df06..bdfeb4736 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Co64Atom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Co64Atom.h @@ -1,62 +1,72 @@ -/*****************************************************************
-|
-| AP4 - co64 Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_CO64_ATOM_H_
-#define _AP4_CO64_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4Array.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| AP4_Co64Atom
-+---------------------------------------------------------------------*/
-class AP4_Co64Atom : public AP4_Atom
-{
- public:
- // methods
- AP4_Co64Atom(AP4_UI64* offsets, AP4_UI32 offset_count);
- AP4_Co64Atom(AP4_Size size, AP4_ByteStream& stream);
- ~AP4_Co64Atom();
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
- AP4_Cardinal GetChunkCount() { return m_EntryCount; }
- AP4_Result GetChunkOffset(AP4_Ordinal chunk, AP4_Offset& chunk_offset);
- AP4_Result SetChunkOffset(AP4_Ordinal chunk, AP4_Offset chunk_offset);
- AP4_Result AdjustChunkOffsets(AP4_Offset offset);
-
- private:
- AP4_UI64* m_Entries;
- AP4_UI32 m_EntryCount;
-};
-
-#endif // _AP4_CO64_ATOM_H_
+/***************************************************************** +| +| AP4 - co64 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_CO64_ATOM_H_ +#define _AP4_CO64_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_Co64Atom ++---------------------------------------------------------------------*/ +class AP4_Co64Atom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_Co64Atom, AP4_Atom) + + // class methods + static AP4_Co64Atom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_Co64Atom(AP4_UI64* offsets, AP4_UI32 offset_count); + ~AP4_Co64Atom(); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + AP4_Cardinal GetChunkCount() { return m_EntryCount; } + AP4_UI64* GetChunkOffsets() { return m_Entries; } + AP4_Result GetChunkOffset(AP4_Ordinal chunk, AP4_UI64& chunk_offset); + AP4_Result SetChunkOffset(AP4_Ordinal chunk, AP4_UI64 chunk_offset); + AP4_Result AdjustChunkOffsets(AP4_SI64 delta); + +private: + // methods + AP4_Co64Atom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI64* m_Entries; + AP4_UI32 m_EntryCount; +}; + +#endif // _AP4_CO64_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Command.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Command.cpp new file mode 100644 index 000000000..1dc6958f5 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Command.cpp @@ -0,0 +1,82 @@ +/***************************************************************** +| +| AP4 - Commands +| +| 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 "Ap4Command.h" +#include "Ap4Utils.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_Command) + +/*---------------------------------------------------------------------- +| AP4_Command::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Command::Inspect(AP4_AtomInspector& inspector) +{ + char name[6]; + AP4_FormatString(name, sizeof(name), "[Command:%02x]", m_ClassId); + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(), + m_PayloadSize); + inspector.StartElement(name, info); + inspector.EndElement(); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_UnknownCommand::AP4_UnknownCommand ++---------------------------------------------------------------------*/ +AP4_UnknownCommand::AP4_UnknownCommand(AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_Command(tag, header_size, payload_size) +{ + m_Data.SetDataSize(payload_size); + stream.Read(m_Data.UseData(), payload_size); +} + +/*---------------------------------------------------------------------- +| AP4_UnknownCommand::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_UnknownCommand::WriteFields(AP4_ByteStream& stream) +{ + // write the payload + stream.Write(m_Data.GetData(), m_Data.GetDataSize()); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Command.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Command.h new file mode 100644 index 000000000..50cf8d736 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Command.h @@ -0,0 +1,89 @@ +/***************************************************************** +| +| AP4 - Commands +| +| 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_COMMAND_H_ +#define _AP4_COMMAND_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Expandable.h" +#include "Ap4DynamicCast.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI08 AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_UPDATE = 0x01; +const AP4_UI08 AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_REMOVE = 0x02; +const AP4_UI08 AP4_COMMAND_TAG_ES_DESCRIPTOR_UPDATE = 0x03; +const AP4_UI08 AP4_COMMAND_TAG_ES_DESCRIPTOR_REMOVE = 0x04; +const AP4_UI08 AP4_COMMAND_TAG_IPMP_DESCRIPTOR_UPDATE = 0x05; +const AP4_UI08 AP4_COMMAND_TAG_IPMP_DESCRIPTOR_REMOVE = 0x06; +const AP4_UI08 AP4_COMMAND_TAG_ES_DESCRIPTOR_REMOVE_REF = 0x07; +const AP4_UI08 AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_EXECUTE = 0x08; + +/*---------------------------------------------------------------------- +| AP4_Command ++---------------------------------------------------------------------*/ +class AP4_Command : public AP4_Expandable +{ + public: + AP4_IMPLEMENT_DYNAMIC_CAST(AP4_Command) + + // constructor + AP4_Command(AP4_UI08 tag, AP4_Size header_size, AP4_Size payload_size) : + AP4_Expandable(tag, CLASS_ID_SIZE_08, header_size, payload_size) {} + + // AP4_Exandable methods + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + + // methods + AP4_UI08 GetTag() { return (AP4_UI08)m_ClassId; } +}; + +/*---------------------------------------------------------------------- +| AP4_UnknownCommand ++---------------------------------------------------------------------*/ +class AP4_UnknownCommand : public AP4_Command +{ +public: + // contrusctor + AP4_UnknownCommand(AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size); + + // AP4_Expandable methods + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // members + AP4_DataBuffer m_Data; +}; + +#endif // _AP4_COMMAND_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CommandFactory.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CommandFactory.cpp new file mode 100644 index 000000000..f41312bda --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CommandFactory.cpp @@ -0,0 +1,93 @@ +/***************************************************************** +| +| AP4 - Command Factory +| +| 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 "Ap4CommandFactory.h" +#include "Ap4ObjectDescriptor.h" +#include "Ap4Command.h" +#include "Ap4ByteStream.h" + +/*---------------------------------------------------------------------- +| AP4_CommandFactory::CreateCommandFromStream ++---------------------------------------------------------------------*/ +AP4_Result +AP4_CommandFactory::CreateCommandFromStream(AP4_ByteStream& stream, + AP4_Command*& command) +{ + AP4_Result result; + + // NULL by default + command = NULL; + + // remember current stream offset + AP4_Position offset; + stream.Tell(offset); + + // read descriptor tag + unsigned char tag; + result = stream.ReadUI08(tag); + if (AP4_FAILED(result)) { + stream.Seek(offset); + return result; + } + + // read descriptor size + unsigned long payload_size = 0; + unsigned int header_size = 1; + unsigned int max = 4; + unsigned char ext = 0; + do { + header_size++; + result = stream.ReadUI08(ext); + if (AP4_FAILED(result)) { + stream.Seek(offset); + return result; + } + payload_size = (payload_size<<7) + (ext&0x7F); + } while (--max && (ext&0x80)); + + // create the command + switch (tag) { + case AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_UPDATE: + case AP4_COMMAND_TAG_IPMP_DESCRIPTOR_UPDATE: + command = new AP4_DescriptorUpdateCommand(stream, tag, header_size, payload_size); + break; + + default: + command = new AP4_UnknownCommand(stream, tag, header_size, payload_size); + break; + } + + // skip to the end of the descriptor + stream.Seek(offset+header_size+payload_size); + + return AP4_SUCCESS; +} + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CommandFactory.h index 2c339c1d2..133b35020 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CommandFactory.h @@ -1,59 +1,54 @@ -/*****************************************************************
-|
-| AP4 - data Atom
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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_DATA_ATOM_H_
-#define _AP4_DATA_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4Atom.h"
-#include "Ap4Types.h"
-#include "Ap4Array.h"
-#include "Ap4DataBuffer.h"
-
-/*----------------------------------------------------------------------
-| AP4_DataAtom
-+---------------------------------------------------------------------*/
-class AP4_DataAtom : public AP4_Atom
-{
-public:
- AP4_DataAtom(AP4_Size size,
- AP4_ByteStream& stream);
-
- AP4_Result WriteFields(AP4_ByteStream& stream) { return AP4_FAILURE; }
-
- const AP4_DataBuffer* GetData() const { return &m_Data; }
-
-private:
- AP4_UI32 m_Reserved1;
- AP4_UI32 m_Reserved2;
- AP4_DataBuffer m_Data;
-};
-
-#endif // _AP4_DATA_ATOM_H_
+/***************************************************************** +| +| AP4 - Command Factory +| +| 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_COMMAND_FACTORY_H_ +#define _AP4_COMMAND_FACTORY_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Command.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| AP4_CommandFactory ++---------------------------------------------------------------------*/ +class AP4_CommandFactory +{ + public: + // class methods + static AP4_Result CreateCommandFromStream(AP4_ByteStream& stream, + AP4_Command*& command); +}; + +#endif // _AP4_COMMAND_FACTORY_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Constants.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Constants.h index 5e693f3a7..3d750dd30 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Constants.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Constants.h @@ -2,7 +2,7 @@ | | AP4 - Shared Constants | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,7 +30,7 @@ #define _AP4_CONSTANTS_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #ifndef NULL #define NULL 0 diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ContainerAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ContainerAtom.cpp index f8774ffc1..deee12653 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ContainerAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ContainerAtom.cpp @@ -1,164 +1,268 @@ -/*****************************************************************
-|
-| AP4 - Container Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4Atom.h"
-#include "Ap4Utils.h"
-#include "Ap4ContainerAtom.h"
-#include "Ap4AtomFactory.h"
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::AP4_ContainerAtom
-+---------------------------------------------------------------------*/
-AP4_ContainerAtom::AP4_ContainerAtom(Type type, bool is_full) :
- AP4_Atom(type, is_full)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::AP4_ContainerAtom
-+---------------------------------------------------------------------*/
-AP4_ContainerAtom::AP4_ContainerAtom(Type type, AP4_Size size, bool is_full) :
- AP4_Atom(type, size, is_full)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::AP4_ContainerAtom
-+---------------------------------------------------------------------*/
-AP4_ContainerAtom::AP4_ContainerAtom(Type type,
- AP4_Size size,
- bool is_full,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_Atom(type, size, is_full, stream)
-{
- ReadChildren(atom_factory, stream, size-GetHeaderSize());
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::AP4_ContainerAtom
-+---------------------------------------------------------------------*/
-AP4_ContainerAtom::AP4_ContainerAtom(Type type,
- AP4_Size size,
- bool is_full,
- AP4_ByteStream& stream) :
- AP4_Atom(type, size, is_full, stream)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::ReadChildren
-+---------------------------------------------------------------------*/
-void
-AP4_ContainerAtom::ReadChildren(AP4_AtomFactory& atom_factory,
- AP4_ByteStream& stream,
- AP4_Size size)
-{
- AP4_Atom* atom;
- AP4_Size bytes_available = size;
- while (AP4_SUCCEEDED(
- atom_factory.CreateAtomFromStream(stream, bytes_available, atom, this))) {
- atom->SetParent(this);
- m_Children.Add(atom);
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ContainerAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- return InspectChildren(inspector);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::InspectChildren
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ContainerAtom::InspectChildren(AP4_AtomInspector& inspector)
-{
- // inspect children
- m_Children.Apply(AP4_AtomListInspector(inspector));
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ContainerAtom::WriteFields(AP4_ByteStream& stream)
-{
- // write all children
- return m_Children.Apply(AP4_AtomListWriter(stream));
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::OnChildChanged
-+---------------------------------------------------------------------*/
-void
-AP4_ContainerAtom::OnChildChanged(AP4_Atom*)
-{
- // remcompute our size
- m_Size = GetHeaderSize();
- m_Children.Apply(AP4_AtomSizeAdder(m_Size));
-
- // update our parent
- if (m_Parent) m_Parent->OnChildChanged(this);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::OnChildAdded
-+---------------------------------------------------------------------*/
-void
-AP4_ContainerAtom::OnChildAdded(AP4_Atom* child)
-{
- // update our size
- m_Size += child->GetSize();
-
- // update our parent
- if (m_Parent) m_Parent->OnChildChanged(this);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ContainerAtom::OnChildRemoved
-+---------------------------------------------------------------------*/
-void
-AP4_ContainerAtom::OnChildRemoved(AP4_Atom* child)
-{
- // update our size
- m_Size -= child->GetSize();
-
- // update our parent
- if (m_Parent) m_Parent->OnChildChanged(this);
-}
+/***************************************************************** +| +| AP4 - Container 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 "Ap4Atom.h" +#include "Ap4Utils.h" +#include "Ap4ContainerAtom.h" +#include "Ap4AtomFactory.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_ContainerAtom) + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::AP4_ContainerAtom ++---------------------------------------------------------------------*/ +AP4_ContainerAtom* +AP4_ContainerAtom::Create(Type type, + AP4_UI64 size, + bool is_full, + bool force_64, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) +{ + if (is_full) { + AP4_UI32 version; + AP4_UI32 flags; + if (AP4_FAILED(AP4_Atom::ReadFullHeader(stream, version, flags))) return NULL; + + // special case for 'meta' atoms, because Apple sometimes creates them as + // regular (non-full) atoms. This is bogus, but we can try to detect it + if (type == AP4_ATOM_TYPE_META) { + AP4_UI32 phantom_size = (version<<24)|flags; + if (phantom_size >= 8 && size >= 16) { + // version+flags looks like a size. read the next 4 bytes just + // to be sure it is a hdlr atom + AP4_UI32 peek; + if (AP4_FAILED(stream.ReadUI32(peek))) return NULL; + if (peek == AP4_ATOM_TYPE_HDLR) { + // rewind the stream by 8 bytes + AP4_Position position; + stream.Tell(position); + stream.Seek(position-8); + + // create a non-full container + return new AP4_ContainerAtom(type, size, force_64, stream, atom_factory); + } + } + } + + return new AP4_ContainerAtom(type, size, force_64, version, flags, stream, atom_factory); + } else { + return new AP4_ContainerAtom(type, size, force_64, stream, atom_factory); + } +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::AP4_ContainerAtom ++---------------------------------------------------------------------*/ +AP4_ContainerAtom::AP4_ContainerAtom(Type type) : + AP4_Atom(type, AP4_ATOM_HEADER_SIZE) +{ +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::AP4_ContainerAtom ++---------------------------------------------------------------------*/ +AP4_ContainerAtom::AP4_ContainerAtom(Type type, AP4_UI32 version, AP4_UI32 flags) : + AP4_Atom(type, AP4_FULL_ATOM_HEADER_SIZE, version, flags) +{ +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::AP4_ContainerAtom ++---------------------------------------------------------------------*/ +AP4_ContainerAtom::AP4_ContainerAtom(Type type, AP4_UI64 size, bool force_64) : + AP4_Atom(type, size, force_64) +{ +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::AP4_ContainerAtom ++---------------------------------------------------------------------*/ +AP4_ContainerAtom::AP4_ContainerAtom(Type type, + AP4_UI64 size, + bool force_64, + AP4_UI32 version, + AP4_UI32 flags) : + AP4_Atom(type, size, force_64, version, flags) +{ +} + + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::AP4_ContainerAtom ++---------------------------------------------------------------------*/ +AP4_ContainerAtom::AP4_ContainerAtom(Type type, + AP4_UI64 size, + bool force_64, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_Atom(type, size, force_64) +{ + ReadChildren(atom_factory, stream, size-GetHeaderSize()); +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::AP4_ContainerAtom ++---------------------------------------------------------------------*/ +AP4_ContainerAtom::AP4_ContainerAtom(Type type, + AP4_UI64 size, + bool force_64, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_Atom(type, size, force_64, version, flags) +{ + ReadChildren(atom_factory, stream, size-GetHeaderSize()); +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::Clone ++---------------------------------------------------------------------*/ +AP4_Atom* +AP4_ContainerAtom::Clone() +{ + AP4_ContainerAtom* clone; + if (m_IsFull) { + clone = new AP4_ContainerAtom(m_Type, m_Version, m_Flags); + } else { + clone = new AP4_ContainerAtom(m_Type); + } + + AP4_List<AP4_Atom>::Item* child_item = m_Children.FirstItem(); + while (child_item) { + AP4_Atom* child_clone = child_item->GetData()->Clone(); + if (child_clone) clone->AddChild(child_clone); + child_item = child_item->GetNext(); + } + + return clone; +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::ReadChildren ++---------------------------------------------------------------------*/ +void +AP4_ContainerAtom::ReadChildren(AP4_AtomFactory& atom_factory, + AP4_ByteStream& stream, + AP4_UI64 size) +{ + AP4_Atom* atom; + AP4_LargeSize bytes_available = size; + + // save and switch the factory's context + atom_factory.PushContext(m_Type); + + while (AP4_SUCCEEDED( + atom_factory.CreateAtomFromStream(stream, bytes_available, atom))) { + atom->SetParent(this); + m_Children.Add(atom); + } + + // restore the saved context + atom_factory.PopContext(); +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ContainerAtom::InspectFields(AP4_AtomInspector& inspector) +{ + return InspectChildren(inspector); +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::InspectChildren ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ContainerAtom::InspectChildren(AP4_AtomInspector& inspector) +{ + // inspect children + m_Children.Apply(AP4_AtomListInspector(inspector)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ContainerAtom::WriteFields(AP4_ByteStream& stream) +{ + // write all children + return m_Children.Apply(AP4_AtomListWriter(stream)); +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::OnChildChanged ++---------------------------------------------------------------------*/ +void +AP4_ContainerAtom::OnChildChanged(AP4_Atom*) +{ + // remcompute our size + AP4_UI64 size = GetHeaderSize(); + m_Children.Apply(AP4_AtomSizeAdder(size)); + SetSize(size); + + // update our parent + if (m_Parent) m_Parent->OnChildChanged(this); +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::OnChildAdded ++---------------------------------------------------------------------*/ +void +AP4_ContainerAtom::OnChildAdded(AP4_Atom* child) +{ + // update our size + SetSize(GetSize()+child->GetSize()); + + // update our parent + if (m_Parent) m_Parent->OnChildChanged(this); +} + +/*---------------------------------------------------------------------- +| AP4_ContainerAtom::OnChildRemoved ++---------------------------------------------------------------------*/ +void +AP4_ContainerAtom::OnChildRemoved(AP4_Atom* child) +{ + // update our size + SetSize(GetSize()-child->GetSize()); + + // update our parent + if (m_Parent) m_Parent->OnChildChanged(this); +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ContainerAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ContainerAtom.h index ed68726b8..b19e18637 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ContainerAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ContainerAtom.h @@ -2,7 +2,7 @@ | | AP4 - Container Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,52 +30,69 @@ #define _AP4_CONTAINER_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Types.h" #include "Ap4List.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| class references +| class references +---------------------------------------------------------------------*/ class AP4_ByteStream; class AP4_AtomFactory; /*---------------------------------------------------------------------- -| AP4_ContainerAtom +| AP4_ContainerAtom +---------------------------------------------------------------------*/ -class AP4_ContainerAtom : public AP4_Atom, public AP4_AtomParent { +class AP4_ContainerAtom : public AP4_Atom, public AP4_AtomParent +{ public: + AP4_IMPLEMENT_DYNAMIC_CAST_D2(AP4_ContainerAtom, AP4_Atom, AP4_AtomParent) + + // class methods + static AP4_ContainerAtom* Create(Type type, + AP4_UI64 size, + bool is_full, + bool force_64, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + // methods - AP4_ContainerAtom(Type type, bool is_full = false); - AP4_ContainerAtom(Type type, - AP4_Size size, - bool is_full, - AP4_ByteStream& stream, - AP4_AtomFactory& atom_factory); - AP4_ContainerAtom(Type type, - AP4_Size size, - bool is_full, - AP4_ByteStream& stream); + explicit AP4_ContainerAtom(Type type); + explicit AP4_ContainerAtom(Type type, AP4_UI32 version, AP4_UI32 flags); + explicit AP4_ContainerAtom(Type type, AP4_UI64 size, bool force_64); + explicit AP4_ContainerAtom(Type type, AP4_UI64 size, bool force_64, AP4_UI32 version, AP4_UI32 flags); AP4_List<AP4_Atom>& GetChildren() { return m_Children; } virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result InspectChildren(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); - + virtual AP4_Atom* Clone(); + // AP4_AtomParent methods - void OnChildChanged(AP4_Atom* child); - void OnChildAdded(AP4_Atom* child); - void OnChildRemoved(AP4_Atom* child); + virtual void OnChildChanged(AP4_Atom* child); + virtual void OnChildAdded(AP4_Atom* child); + virtual void OnChildRemoved(AP4_Atom* child); protected: - // constructor - AP4_ContainerAtom(Type type, AP4_Size size, bool is_full = false); + // constructors + AP4_ContainerAtom(Type type, + AP4_UI64 size, + bool force_64, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + AP4_ContainerAtom(Type type, + AP4_UI64 size, + bool force_64, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); // methods void ReadChildren(AP4_AtomFactory& atom_factory, AP4_ByteStream& stream, - AP4_Size size); + AP4_UI64 size); }; #endif // _AP4_CONTAINER_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CttsAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CttsAtom.cpp index 5cbdf17a0..feae00103 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CttsAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CttsAtom.cpp @@ -1,115 +1,211 @@ -/*****************************************************************
-|
-| AP4 - ctts Atoms
-|
-| Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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 "Ap4.h"
-#include "Ap4CttsAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_CttsAtom::AP4_CttsAtom
-+---------------------------------------------------------------------*/
-AP4_CttsAtom::AP4_CttsAtom(AP4_Size size, AP4_ByteStream& stream) :
- AP4_Atom(AP4_ATOM_TYPE_CTTS, size, true, stream)
-{
- AP4_UI32 entry_count;
- stream.ReadUI32(entry_count);
- while (entry_count--) {
- AP4_UI32 sample_count;
- AP4_UI32 sample_offset;
- if (stream.ReadUI32(sample_count) == AP4_SUCCESS &&
- stream.ReadUI32(sample_offset) == AP4_SUCCESS) {
- m_Entries.Append(AP4_CttsTableEntry(sample_count,
- sample_offset));
- }
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_CttsAtom::GetCtsOffset
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_CttsAtom::GetCtsOffset(AP4_Ordinal sample, AP4_UI32& cts_offset)
-{
- AP4_Ordinal current_sample = 0;
-
- for (unsigned int i = 0; i < m_Entries.ItemCount(); i++) {
- AP4_CttsTableEntry& entry = m_Entries[i];
-
- current_sample += entry.m_SampleCount;
- // check if we have the right entry
- if (current_sample >= sample) {
- cts_offset = entry.m_SampleOffset;
- return AP4_SUCCESS;
- }
- }
-
- // sample is greater than the number of samples
- return AP4_FAILURE;
-}
-
-/*----------------------------------------------------------------------
-| AP4_CttsAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_CttsAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // write the entry count
- AP4_Cardinal entry_count = m_Entries.ItemCount();
- result = stream.WriteUI32(entry_count);
- if (AP4_FAILED(result)) return result;
-
- // write the entries
- for (AP4_Ordinal i=0; i<entry_count; i++) {
- // sample count
- result = stream.WriteUI32(m_Entries[i].m_SampleCount);
- if (AP4_FAILED(result)) return result;
-
- // time offset
- result = stream.WriteUI32(m_Entries[i].m_SampleOffset);
- if (AP4_FAILED(result)) return result;
- }
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_CttsAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_CttsAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("entry_count", m_Entries.ItemCount());
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - ctts 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 "Ap4CttsAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_CttsAtom) + +/*---------------------------------------------------------------------- +| AP4_CttsAtom::Create ++---------------------------------------------------------------------*/ +AP4_CttsAtom* +AP4_CttsAtom::Create(AP4_UI32 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_CttsAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_CttsAtom::AP4_CttsAtom ++---------------------------------------------------------------------*/ +AP4_CttsAtom::AP4_CttsAtom() : + AP4_Atom(AP4_ATOM_TYPE_CTTS, AP4_FULL_ATOM_HEADER_SIZE+4, 0, 0) +{ + m_LookupCache.sample = 0; + m_LookupCache.entry_index = 0; +} + +/*---------------------------------------------------------------------- +| AP4_CttsAtom::AP4_CttsAtom ++---------------------------------------------------------------------*/ +AP4_CttsAtom::AP4_CttsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_CTTS, size, version, flags) +{ + m_LookupCache.sample = 0; + m_LookupCache.entry_index = 0; + + AP4_UI32 entry_count; + stream.ReadUI32(entry_count); + m_Entries.SetItemCount(entry_count); + unsigned char* buffer = new unsigned char[entry_count*8]; + AP4_Result result = stream.Read(buffer, entry_count*8); + if (AP4_FAILED(result)) { + delete[] buffer; + return; + } + bool use_quicktime_format = false; + AP4_SI32 quicktime_min_offset = 0; + for (unsigned i=0; i<entry_count; i++) { + m_Entries[i].m_SampleCount = AP4_BytesToUInt32BE(&buffer[i*8 ]); + AP4_UI32 offset = AP4_BytesToUInt32BE(&buffer[i*8+4]); + if (offset & 0x80000000) { + use_quicktime_format = true; + AP4_SI32 noffset = (AP4_SI32)offset; + if (noffset < quicktime_min_offset) quicktime_min_offset = noffset; + } + m_Entries[i].m_SampleOffset = offset; + } + delete[] buffer; + + // in the quicktime format, the offsets can be positive or negative, so + // we need to adjust for them here + if (use_quicktime_format) { + for (unsigned i=0; i<entry_count; i++) { + m_Entries[i].m_SampleOffset -= quicktime_min_offset; + } + } +} + +/*---------------------------------------------------------------------- +| AP4_CttsAtom::AddEntry ++---------------------------------------------------------------------*/ +AP4_Result +AP4_CttsAtom::AddEntry(AP4_UI32 count, AP4_UI32 cts_offset) +{ + m_Entries.Append(AP4_CttsTableEntry(count, cts_offset)); + m_Size32 += 8; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_CttsAtom::GetCtsOffset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_CttsAtom::GetCtsOffset(AP4_Ordinal sample, AP4_UI32& cts_offset) +{ + // default value + cts_offset = 0; + + // sample indexes start at 1 + if (sample == 0) return AP4_ERROR_OUT_OF_RANGE; + + // check the lookup cache + AP4_Ordinal lookup_start = 0; + AP4_Ordinal sample_start = 0; + if (sample >= m_LookupCache.sample) { + // start from the cached entry + lookup_start = m_LookupCache.entry_index; + sample_start = m_LookupCache.sample; + } + + for (AP4_Ordinal i = lookup_start; i < m_Entries.ItemCount(); i++) { + AP4_CttsTableEntry& entry = m_Entries[i]; + + // check if we have reached the sample + if (sample <= sample_start+entry.m_SampleCount) { + // we are within the sample range for the current entry + cts_offset = entry.m_SampleOffset; + + // update the lookup cache + m_LookupCache.entry_index = i; + m_LookupCache.sample = sample_start; + + return AP4_SUCCESS; + } + + // update the upper bound + sample_start += entry.m_SampleCount; + } + + // sample is greater than the number of samples + return AP4_ERROR_OUT_OF_RANGE; +} + +/*---------------------------------------------------------------------- +| AP4_CttsAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_CttsAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // write the entry count + AP4_Cardinal entry_count = m_Entries.ItemCount(); + result = stream.WriteUI32(entry_count); + if (AP4_FAILED(result)) return result; + + // write the entries + for (AP4_Ordinal i=0; i<entry_count; i++) { + // sample count + result = stream.WriteUI32(m_Entries[i].m_SampleCount); + if (AP4_FAILED(result)) return result; + + // time offset + result = stream.WriteUI32(m_Entries[i].m_SampleOffset); + if (AP4_FAILED(result)) return result; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_CttsAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_CttsAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("entry_count", m_Entries.ItemCount()); + + if (inspector.GetVerbosity() >= 2) { + char header[32]; + char value[64]; + for (AP4_Ordinal i=0; i<m_Entries.ItemCount(); i++) { + AP4_FormatString(header, sizeof(header), "entry %8d", i); + AP4_FormatString(value, sizeof(value), "count=%d, offset=%d", + m_Entries[i].m_SampleCount, + m_Entries[i].m_SampleOffset); + inspector.AddField(header, value); + } + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CttsAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CttsAtom.h index 9f5dab8ff..0f86c8399 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CttsAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CttsAtom.h @@ -1,73 +1,96 @@ -/*****************************************************************
-|
-| AP4 - ctts Atoms
-|
-| Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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_CTTS_ATOM_H_
-#define _AP4_CTTS_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4Atom.h"
-#include "Ap4Types.h"
-#include "Ap4Array.h"
-
-/*----------------------------------------------------------------------
-| AP4_CttsTableEntry
-+---------------------------------------------------------------------*/
-class AP4_CttsTableEntry {
- public:
- AP4_CttsTableEntry() :
- m_SampleCount(0),
- m_SampleOffset(0) {}
- AP4_CttsTableEntry(AP4_Cardinal sample_count,
- AP4_Offset sample_offset) :
- m_SampleCount(sample_count),
- m_SampleOffset(sample_offset) {}
-
- AP4_Cardinal m_SampleCount;
- AP4_Offset m_SampleOffset;
-};
-
-/*----------------------------------------------------------------------
-| AP4_CttsAtom
-+---------------------------------------------------------------------*/
-class AP4_CttsAtom : public AP4_Atom
-{
- public:
- // methods
- AP4_CttsAtom(AP4_Size size, AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
- virtual AP4_Result GetCtsOffset(AP4_Ordinal sample,
- AP4_UI32& cts_offset);
-
- private:
- AP4_Array<AP4_CttsTableEntry> m_Entries;
-};
-
-#endif // _AP4_CTTS_ATOM_H_
+/***************************************************************** +| +| AP4 - ctts 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_CTTS_ATOM_H_ +#define _AP4_CTTS_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" +#include "Ap4Types.h" +#include "Ap4Array.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| AP4_CttsTableEntry ++---------------------------------------------------------------------*/ +class AP4_CttsTableEntry { + public: + AP4_CttsTableEntry() : + m_SampleCount(0), + m_SampleOffset(0) {} + AP4_CttsTableEntry(AP4_UI32 sample_count, + AP4_UI32 sample_offset) : + m_SampleCount(sample_count), + m_SampleOffset(sample_offset) {} + + AP4_UI32 m_SampleCount; + AP4_UI32 m_SampleOffset; +}; + +/*---------------------------------------------------------------------- +| AP4_CttsAtom ++---------------------------------------------------------------------*/ +class AP4_CttsAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_CttsAtom, AP4_Atom) + + // class methods + static AP4_CttsAtom* Create(AP4_UI32 size, AP4_ByteStream& stream); + + // constructor + AP4_CttsAtom(); + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + AP4_Result AddEntry(AP4_UI32 count, AP4_UI32 cts_offset); + AP4_Result GetCtsOffset(AP4_Ordinal sample, AP4_UI32& cts_offset); + +private: + // methods + AP4_CttsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_Array<AP4_CttsTableEntry> m_Entries; + struct { + AP4_Ordinal sample; + AP4_Ordinal entry_index; + } m_LookupCache; +}; + +#endif // _AP4_CTTS_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataAtom.cpp deleted file mode 100644 index 97c72d283..000000000 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataAtom.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/*****************************************************************
-|
-| AP4 - data Atom
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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 "Ap4DataAtom.h"
-
-/*----------------------------------------------------------------------
-| AP4_DataAtom::AP4_DataAtom
-+---------------------------------------------------------------------*/
-
-AP4_DataAtom::AP4_DataAtom(AP4_Size size,
- AP4_ByteStream& stream)
- : AP4_Atom(AP4_ATOM_TYPE_DATA)
-{
- size -= AP4_ATOM_HEADER_SIZE;
-
- stream.ReadUI32(m_Reserved1);
- stream.ReadUI32(m_Reserved2);
-
- size -= 8;
-
- m_Data.SetDataSize(size);
- stream.Read(m_Data.UseData(), size);
-}
diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataBuffer.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataBuffer.cpp index 36e8ca25e..507a8f96f 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataBuffer.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataBuffer.cpp @@ -2,7 +2,7 @@ | | AP4 - Data Buffer | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,12 +27,13 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4DataBuffer.h" +#include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_DataBuffer::AP4_DataBuffer +| AP4_DataBuffer::AP4_DataBuffer +---------------------------------------------------------------------*/ AP4_DataBuffer::AP4_DataBuffer() : m_BufferIsLocal(true), @@ -43,7 +44,7 @@ AP4_DataBuffer::AP4_DataBuffer() : } /*---------------------------------------------------------------------- -| AP4_DataBuffer::AP4_DataBuffer +| AP4_DataBuffer::AP4_DataBuffer +---------------------------------------------------------------------*/ AP4_DataBuffer::AP4_DataBuffer(AP4_Size buffer_size) : m_BufferIsLocal(true), @@ -51,11 +52,26 @@ AP4_DataBuffer::AP4_DataBuffer(AP4_Size buffer_size) : m_BufferSize(buffer_size), m_DataSize(0) { - m_Buffer = DNew AP4_Byte[buffer_size]; + m_Buffer = new AP4_Byte[buffer_size]; } /*---------------------------------------------------------------------- -| AP4_DataBuffer::AP4_DataBuffer +| AP4_DataBuffer::AP4_DataBuffer ++---------------------------------------------------------------------*/ +AP4_DataBuffer::AP4_DataBuffer(const void* data, AP4_Size data_size) : + m_BufferIsLocal(true), + m_Buffer(NULL), + m_BufferSize(data_size), + m_DataSize(data_size) +{ + if (data && data_size) { + m_Buffer = new AP4_Byte[data_size]; + AP4_CopyMemory(m_Buffer, data, data_size); + } +} + +/*---------------------------------------------------------------------- +| AP4_DataBuffer::AP4_DataBuffer +---------------------------------------------------------------------*/ AP4_DataBuffer::AP4_DataBuffer(const AP4_DataBuffer& other) : m_BufferIsLocal(true), @@ -63,12 +79,12 @@ AP4_DataBuffer::AP4_DataBuffer(const AP4_DataBuffer& other) : m_BufferSize(other.m_DataSize), m_DataSize(other.m_DataSize) { - m_Buffer = DNew AP4_Byte[m_BufferSize]; - memcpy(m_Buffer, other.m_Buffer, m_BufferSize); + m_Buffer = new AP4_Byte[m_BufferSize]; + AP4_CopyMemory(m_Buffer, other.m_Buffer, m_BufferSize); } /*---------------------------------------------------------------------- -| AP4_DataBuffer::~AP4_DataBuffer +| AP4_DataBuffer::~AP4_DataBuffer +---------------------------------------------------------------------*/ AP4_DataBuffer::~AP4_DataBuffer() { @@ -78,7 +94,21 @@ AP4_DataBuffer::~AP4_DataBuffer() } /*---------------------------------------------------------------------- -| AP4_DataBuffer::SetBuffer +| AP4_DataBuffer::Reserve ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DataBuffer::Reserve(AP4_Size size) +{ + if (size <= m_BufferSize) return AP4_SUCCESS; + + // try doubling the buffer to accomodate for the new size + AP4_Size new_size = m_BufferSize*2+1024; + if (new_size < size) new_size = size; + return SetBufferSize(new_size); +} + +/*---------------------------------------------------------------------- +| AP4_DataBuffer::SetBuffer +---------------------------------------------------------------------*/ AP4_Result AP4_DataBuffer::SetBuffer(AP4_Byte* buffer, AP4_Size buffer_size) @@ -97,7 +127,7 @@ AP4_DataBuffer::SetBuffer(AP4_Byte* buffer, AP4_Size buffer_size) } /*---------------------------------------------------------------------- -| AP4_DataBuffer::SetBufferSize +| AP4_DataBuffer::SetBufferSize +---------------------------------------------------------------------*/ AP4_Result AP4_DataBuffer::SetBufferSize(AP4_Size buffer_size) @@ -111,7 +141,7 @@ AP4_DataBuffer::SetBufferSize(AP4_Size buffer_size) } /*---------------------------------------------------------------------- -| AP4_DataBuffer::SetDataSize +| AP4_DataBuffer::SetDataSize +---------------------------------------------------------------------*/ AP4_Result AP4_DataBuffer::SetDataSize(AP4_Size size) @@ -129,10 +159,10 @@ AP4_DataBuffer::SetDataSize(AP4_Size size) } /*---------------------------------------------------------------------- -| AP4_DataBuffer::SetData +| AP4_DataBuffer::SetData +---------------------------------------------------------------------*/ AP4_Result -AP4_DataBuffer::SetData(AP4_Byte* data, AP4_Size size) +AP4_DataBuffer::SetData(const AP4_Byte* data, AP4_Size size) { if (size > m_BufferSize) { if (m_BufferIsLocal) { @@ -150,7 +180,7 @@ AP4_DataBuffer::SetData(AP4_Byte* data, AP4_Size size) /*---------------------------------------------------------------------- -| AP4_DataBuffer::ReallocateBuffer +| AP4_DataBuffer::ReallocateBuffer +---------------------------------------------------------------------*/ AP4_Result AP4_DataBuffer::ReallocateBuffer(AP4_Size size) @@ -159,7 +189,7 @@ AP4_DataBuffer::ReallocateBuffer(AP4_Size size) if (m_DataSize > size) return AP4_FAILURE; // allocate a new buffer - AP4_Byte* new_buffer = DNew AP4_Byte[size]; + AP4_Byte* new_buffer = new AP4_Byte[size]; // copy the contents of the previous buffer ,is any if (m_Buffer && m_DataSize) { diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataBuffer.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataBuffer.h index 529e842d6..64e89f981 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataBuffer.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DataBuffer.h @@ -2,7 +2,7 @@ | | AP4 - Data Buffer Objects | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,12 +30,12 @@ #define _AP4_DATA_BUFFER_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" +#include "Ap4Types.h" /*---------------------------------------------------------------------- -| AP4_DataBuffer +| AP4_DataBuffer +---------------------------------------------------------------------*/ class AP4_DataBuffer { @@ -43,20 +43,24 @@ class AP4_DataBuffer // constructors & destructor AP4_DataBuffer(); AP4_DataBuffer(AP4_Size size); + AP4_DataBuffer(const void* data, AP4_Size data_size); AP4_DataBuffer(const AP4_DataBuffer& other); virtual ~AP4_DataBuffer(); // data buffer handling methods - virtual AP4_Result SetBuffer(AP4_Byte* buffer, AP4_Size buffer_size); - virtual AP4_Result SetBufferSize(AP4_Size buffer_size); - virtual AP4_Size GetBufferSize() const { return m_BufferSize; } + AP4_Result SetBuffer(AP4_Byte* buffer, AP4_Size buffer_size); + AP4_Result SetBufferSize(AP4_Size buffer_size); + AP4_Size GetBufferSize() const { return m_BufferSize; } // data handling methods - virtual const AP4_Byte* GetData() const { return m_Buffer; } - virtual AP4_Byte* UseData() { return m_Buffer; }; - virtual AP4_Size GetDataSize() const { return m_DataSize; } - virtual AP4_Result SetDataSize(AP4_Size size); - virtual AP4_Result SetData(AP4_Byte* data, AP4_Size data_size); + const AP4_Byte* GetData() const { return m_Buffer; } + AP4_Byte* UseData() { return m_Buffer; }; + AP4_Size GetDataSize() const { return m_DataSize; } + AP4_Result SetDataSize(AP4_Size size); + AP4_Result SetData(const AP4_Byte* data, AP4_Size data_size); + + // memory management + AP4_Result Reserve(AP4_Size size); protected: // members @@ -67,6 +71,10 @@ class AP4_DataBuffer // methods AP4_Result ReallocateBuffer(AP4_Size size); + +private: + // forbid this + AP4_DataBuffer& operator=(const AP4_DataBuffer& other); }; #endif // _AP4_DATA_BUFFER_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Debug.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Debug.cpp index b9903d5c5..ee09ae84d 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Debug.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Debug.cpp @@ -2,7 +2,7 @@ | | AP4 - Debug Support | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,30 +27,32 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include <stdarg.h> #include <stdio.h> -#include "Ap4.h" +#include "Ap4Config.h" +#include "Ap4Types.h" +#include "Ap4Utils.h" #include "Ap4Debug.h" /*---------------------------------------------------------------------- -| constants +| constants +---------------------------------------------------------------------*/ const int AP4_DEBUG_MAX_BUFFER = 1024; /*---------------------------------------------------------------------- -| AP4_Print +| AP4_Print +---------------------------------------------------------------------*/ static void AP4_Print(const char* message) { - printf(message); + printf("%s", message); } /*---------------------------------------------------------------------- -| AP4_Debug +| AP4_Debug +---------------------------------------------------------------------*/ void AP4_Debug(const char* format, ...) @@ -60,7 +62,7 @@ AP4_Debug(const char* format, ...) va_start(args, format); char buffer[AP4_DEBUG_MAX_BUFFER]; - vsnprintf(buffer, sizeof(buffer), format, args); + AP4_FormatStringVN(buffer, sizeof(buffer), format, args); AP4_Print(buffer); va_end(args); diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Debug.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Debug.h index f99aaa79e..cf8613725 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Debug.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Debug.h @@ -2,7 +2,7 @@ | | AP4 - Debug Support | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,17 +30,17 @@ #define _AP4_DEBUG_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Config.h" /*---------------------------------------------------------------------- -| AP4_Debug +| AP4_Debug +---------------------------------------------------------------------*/ extern void AP4_Debug(const char* format, ...); /*---------------------------------------------------------------------- -| AP4_ASSERT +| AP4_ASSERT +---------------------------------------------------------------------*/ #if defined (AP4_CONFIG_HAVE_ASSERT_H) #include <assert.h> diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderConfigDescriptor.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderConfigDescriptor.cpp index de442df29..45b348f2d 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderConfigDescriptor.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderConfigDescriptor.cpp @@ -2,7 +2,7 @@ | | AP4 - DecoderConfig Descriptors | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,15 +27,21 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4DecoderConfigDescriptor.h" #include "Ap4DescriptorFactory.h" #include "Ap4Utils.h" +#include "Ap4ByteStream.h" +#include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_DecoderConfigDescriptor) + +/*---------------------------------------------------------------------- +| AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor +---------------------------------------------------------------------*/ AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor( AP4_UI08 stream_type, @@ -47,6 +53,7 @@ AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor( AP4_Descriptor(AP4_DESCRIPTOR_TAG_DECODER_CONFIG, 2, 13), m_StreamType(stream_type), m_ObjectTypeIndication(oti), + m_UpStream(false), m_BufferSize(buffer_size), m_MaxBitrate(max_bitrate), m_AverageBitrate(avg_bitrate) @@ -59,7 +66,7 @@ AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor( } /*---------------------------------------------------------------------- -| AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor +| AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor +---------------------------------------------------------------------*/ AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor( AP4_ByteStream& stream, AP4_Size header_size, AP4_Size payload_size) : @@ -68,7 +75,7 @@ AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor( payload_size) { // record the start position - AP4_Offset start; + AP4_Position start; stream.Tell(start); // read descriptor fields @@ -82,7 +89,7 @@ AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor( stream.ReadUI32(m_AverageBitrate); // read other descriptors - AP4_SubStream* substream = DNew AP4_SubStream(stream, start+13, payload_size-13); + AP4_SubStream* substream = new AP4_SubStream(stream, start+13, payload_size-13); AP4_Descriptor* descriptor = NULL; while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream, descriptor) @@ -93,7 +100,7 @@ AP4_DecoderConfigDescriptor::AP4_DecoderConfigDescriptor( } /*---------------------------------------------------------------------- -| AP4_DecoderConfigDescriptor::~AP4_DecoderConfigDescriptor +| AP4_DecoderConfigDescriptor::~AP4_DecoderConfigDescriptor +---------------------------------------------------------------------*/ AP4_DecoderConfigDescriptor::~AP4_DecoderConfigDescriptor() { @@ -101,7 +108,7 @@ AP4_DecoderConfigDescriptor::~AP4_DecoderConfigDescriptor() } /*---------------------------------------------------------------------- -| AP4_DecoderConfigDescriptor::WriteFields +| AP4_DecoderConfigDescriptor::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_DecoderConfigDescriptor::WriteFields(AP4_ByteStream& stream) @@ -119,16 +126,16 @@ AP4_DecoderConfigDescriptor::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_DecoderConfigDescriptor::Inspect +| AP4_DecoderConfigDescriptor::Inspect +---------------------------------------------------------------------*/ AP4_Result AP4_DecoderConfigDescriptor::Inspect(AP4_AtomInspector& inspector) { char info[64]; - AP4_StringFormat(info, sizeof(info), "size=%ld+%ld", + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", GetHeaderSize(), m_PayloadSize); - inspector.StartElement("#[DecoderConfig]", info); + inspector.StartElement("[DecoderConfig]", info); inspector.AddField("stream_type", m_StreamType); inspector.AddField("object_type", m_ObjectTypeIndication); inspector.AddField("up_stream", m_UpStream); @@ -145,7 +152,7 @@ AP4_DecoderConfigDescriptor::Inspect(AP4_AtomInspector& inspector) } /*---------------------------------------------------------------------- -| AP4_DecoderConfigDescriptor::GetDecoderSpecificInfoDescriptor +| AP4_DecoderConfigDescriptor::GetDecoderSpecificInfoDescriptor +---------------------------------------------------------------------*/ const AP4_DecoderSpecificInfoDescriptor* AP4_DecoderConfigDescriptor::GetDecoderSpecificInfoDescriptor() const @@ -158,7 +165,7 @@ AP4_DecoderConfigDescriptor::GetDecoderSpecificInfoDescriptor() const // return it if (AP4_SUCCEEDED(result)) { - return dynamic_cast<AP4_DecoderSpecificInfoDescriptor*>(descriptor); + return AP4_DYNAMIC_CAST(AP4_DecoderSpecificInfoDescriptor, descriptor); } else { return NULL; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderConfigDescriptor.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderConfigDescriptor.h index 1b7e02a77..831bbf9e5 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderConfigDescriptor.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderConfigDescriptor.h @@ -2,7 +2,7 @@ | | AP4 - DecoderConfig Descriptor | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,25 +30,31 @@ #define _AP4_DECODER_CONFIG_DESCRIPTOR_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" +#include "Ap4Types.h" #include "Ap4List.h" #include "Ap4Descriptor.h" #include "Ap4DecoderSpecificInfoDescriptor.h" /*---------------------------------------------------------------------- -| constants +| class references +---------------------------------------------------------------------*/ -const AP4_Descriptor::Tag AP4_DESCRIPTOR_TAG_DECODER_CONFIG = 0x04; +class AP4_ByteStream; /*---------------------------------------------------------------------- -| AP4_DecoderConfigDescriptor +| constants ++---------------------------------------------------------------------*/ +const AP4_UI08 AP4_DESCRIPTOR_TAG_DECODER_CONFIG = 0x04; + +/*---------------------------------------------------------------------- +| AP4_DecoderConfigDescriptor +---------------------------------------------------------------------*/ class AP4_DecoderConfigDescriptor : public AP4_Descriptor { public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_DecoderConfigDescriptor, AP4_Descriptor) + // methods AP4_DecoderConfigDescriptor(AP4_UI08 stream_type, AP4_UI08 oti, diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderSpecificInfoDescriptor.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderSpecificInfoDescriptor.cpp index 092458585..8c755964f 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderSpecificInfoDescriptor.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderSpecificInfoDescriptor.cpp @@ -2,7 +2,7 @@ | | AP4 - DecoderSpecificInfo Descriptors | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,15 +27,21 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4DecoderSpecificInfoDescriptor.h" #include "Ap4DescriptorFactory.h" #include "Ap4Utils.h" +#include "Ap4ByteStream.h" +#include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_DecoderSpecificInfoDescriptor::AP4_DecoderSpecificInfoDescriptor +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_DecoderSpecificInfoDescriptor) + +/*---------------------------------------------------------------------- +| AP4_DecoderSpecificInfoDescriptor::AP4_DecoderSpecificInfoDescriptor +---------------------------------------------------------------------*/ AP4_DecoderSpecificInfoDescriptor::AP4_DecoderSpecificInfoDescriptor( const AP4_DataBuffer& data) : @@ -47,7 +53,7 @@ AP4_DecoderSpecificInfoDescriptor::AP4_DecoderSpecificInfoDescriptor( } /*---------------------------------------------------------------------- -| AP4_DecoderSpecificInfoDescriptor::AP4_DecoderSpecificInfoDescriptor +| AP4_DecoderSpecificInfoDescriptor::AP4_DecoderSpecificInfoDescriptor +---------------------------------------------------------------------*/ AP4_DecoderSpecificInfoDescriptor::AP4_DecoderSpecificInfoDescriptor( AP4_ByteStream& stream, AP4_Size header_size, AP4_Size payload_size) : @@ -59,14 +65,14 @@ AP4_DecoderSpecificInfoDescriptor::AP4_DecoderSpecificInfoDescriptor( } /*---------------------------------------------------------------------- -| AP4_DecoderSpecificInfoDescriptor::~AP4_DecoderSpecificInfoDescriptor +| AP4_DecoderSpecificInfoDescriptor::~AP4_DecoderSpecificInfoDescriptor +---------------------------------------------------------------------*/ AP4_DecoderSpecificInfoDescriptor::~AP4_DecoderSpecificInfoDescriptor() { } /*---------------------------------------------------------------------- -| AP4_DecoderSpecificInfoDescriptor::WriteFields +| AP4_DecoderSpecificInfoDescriptor::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_DecoderSpecificInfoDescriptor::WriteFields(AP4_ByteStream& stream) @@ -80,17 +86,17 @@ AP4_DecoderSpecificInfoDescriptor::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_DecoderSpecificInfoDescriptor::Inspect +| AP4_DecoderSpecificInfoDescriptor::Inspect +---------------------------------------------------------------------*/ AP4_Result AP4_DecoderSpecificInfoDescriptor::Inspect(AP4_AtomInspector& inspector) { - char* info = DNew char[m_Info.GetDataSize()*3+1]; + char* info = new char[m_Info.GetDataSize()*3+1]; for (unsigned int i=0; i<m_Info.GetDataSize(); i++) { - AP4_StringFormat(&info[i*3], 3, "%02x ", m_Info.UseData()[i]); + AP4_FormatString(&info[i*3], 4, "%02x ", m_Info.UseData()[i]); } info[m_Info.GetDataSize()*3] = '\0'; - inspector.AddField("#[DecoderSpecificInfo]", info); + inspector.AddField("[DecoderSpecificInfo]", info); delete[] info; return AP4_SUCCESS; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderSpecificInfoDescriptor.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderSpecificInfoDescriptor.h index f5e6e3cd4..8f0611c12 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderSpecificInfoDescriptor.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DecoderSpecificInfoDescriptor.h @@ -2,7 +2,7 @@ | | AP4 - DecoderSpecificInfo Descriptor | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,25 +30,31 @@ #define _AP4_DECODER_SPECIFIC_INFO_DESCRIPTOR_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" +#include "Ap4Types.h" #include "Ap4List.h" #include "Ap4Descriptor.h" #include "Ap4DataBuffer.h" /*---------------------------------------------------------------------- -| constants +| class references +---------------------------------------------------------------------*/ -const AP4_Descriptor::Tag AP4_DESCRIPTOR_TAG_DECODER_SPECIFIC_INFO = 0x05; +class AP4_ByteStream; /*---------------------------------------------------------------------- -| AP4_DecoderSpecificInfoDescriptor +| constants ++---------------------------------------------------------------------*/ +const AP4_UI08 AP4_DESCRIPTOR_TAG_DECODER_SPECIFIC_INFO = 0x05; + +/*---------------------------------------------------------------------- +| AP4_DecoderSpecificInfoDescriptor +---------------------------------------------------------------------*/ class AP4_DecoderSpecificInfoDescriptor : public AP4_Descriptor { public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_DecoderSpecificInfoDescriptor, AP4_Descriptor) + // methods AP4_DecoderSpecificInfoDescriptor(const AP4_DataBuffer& data); AP4_DecoderSpecificInfoDescriptor(AP4_ByteStream& stream, diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Descriptor.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Descriptor.cpp index e9edafbf3..38fb28988 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Descriptor.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Descriptor.cpp @@ -2,7 +2,7 @@ | | AP4 - Descriptors | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,90 +27,57 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4Descriptor.h" #include "Ap4Utils.h" +#include "Ap4ByteStream.h" +#include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_Descriptor::MinHeaderSize +| dynamic cast support +---------------------------------------------------------------------*/ -AP4_Size -AP4_Descriptor::MinHeaderSize(AP4_Size payload_size) -{ - // compute how many bytes are needed to encode the payload size - // plus tag - return 2+(payload_size/128); -} +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_Descriptor) /*---------------------------------------------------------------------- -| AP4_Descriptor::AP4_Descriptor +| AP4_Descriptor::Inspect +---------------------------------------------------------------------*/ -AP4_Descriptor::AP4_Descriptor(Tag tag, - AP4_Size header_size, - AP4_Size payload_size) : - m_Tag(tag), - m_HeaderSize(header_size), - m_PayloadSize(payload_size) +AP4_Result +AP4_Descriptor::Inspect(AP4_AtomInspector& inspector) { - AP4_ASSERT(header_size >= 1+1); - AP4_ASSERT(header_size <= 1+4); + char name[20]; + AP4_FormatString(name, sizeof(name), "[Descriptor:%02x]", m_ClassId); + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(), + m_PayloadSize); + inspector.StartElement(name, info); + inspector.EndElement(); + + return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_Descriptor::Write +| AP4_UnknownDescriptor::AP4_UnknownDescriptor +---------------------------------------------------------------------*/ -AP4_Result -AP4_Descriptor::Write(AP4_ByteStream& stream) +AP4_UnknownDescriptor::AP4_UnknownDescriptor(AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_Descriptor(tag, header_size, payload_size) { - AP4_Result result; - - // write the tag - result = stream.WriteUI08(m_Tag); - if (AP4_FAILED(result)) return result; - - // write the size - AP4_ASSERT(m_HeaderSize-1 <= 8); - AP4_ASSERT(m_HeaderSize >= 2); - unsigned int size = m_PayloadSize; - unsigned char bytes[8]; - - // last bytes of the encoded size - bytes[m_HeaderSize-2] = size&0x7F; - - // leading bytes of the encoded size - for (int i=m_HeaderSize-3; i>=0; i--) { - // move to the next 7 bits - size >>= 7; - - // output a byte with a top bit marker - bytes[i] = (size&0x7F) | 0x80; - } - - result = stream.Write(bytes, m_HeaderSize-1); - if (AP4_FAILED(result)) return result; - - // write the fields - WriteFields(stream); - - return result; + m_Data.SetDataSize(payload_size); + stream.Read(m_Data.UseData(), payload_size); } /*---------------------------------------------------------------------- -| AP4_Descriptor::Inspect +| AP4_UnknownDescriptor::WriteFields +---------------------------------------------------------------------*/ AP4_Result -AP4_Descriptor::Inspect(AP4_AtomInspector& inspector) +AP4_UnknownDescriptor::WriteFields(AP4_ByteStream& stream) { - char name[6]; - AP4_StringFormat(name, sizeof(name), "#[%02x]", m_Tag); - char info[64]; - AP4_StringFormat(info, sizeof(info), "size=%ld+%ld", - GetHeaderSize(), - m_PayloadSize); - inspector.StartElement(name, info); - inspector.EndElement(); + // write the payload + stream.Write(m_Data.GetData(), m_Data.GetDataSize()); return AP4_SUCCESS; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Descriptor.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Descriptor.h index e2e6689f9..7fe0717a1 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Descriptor.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Descriptor.h @@ -2,7 +2,7 @@ | | AP4 - Descriptors | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,58 +30,74 @@ #define _AP4_DESCRIPTOR_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" +#include "Ap4Expandable.h" #include "Ap4List.h" -#include "Ap4Atom.h" +#include "Ap4DynamicCast.h" /*---------------------------------------------------------------------- -| AP4_Descriptor +| class references +---------------------------------------------------------------------*/ -class AP4_Descriptor +class AP4_ByteStream; +class AP4_AtomInspector; + +/*---------------------------------------------------------------------- +| AP4_Descriptor ++---------------------------------------------------------------------*/ +class AP4_Descriptor : public AP4_Expandable { public: - // types - typedef unsigned char Tag; + AP4_IMPLEMENT_DYNAMIC_CAST(AP4_Descriptor) + + // constructor + AP4_Descriptor(AP4_UI08 tag, AP4_Size header_size, AP4_Size payload_size) : + AP4_Expandable(tag, CLASS_ID_SIZE_08, header_size, payload_size) {} - // class methods - static AP4_Size MinHeaderSize(AP4_Size payload_size); + // AP4_Exandable methods + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); // methods - AP4_Descriptor(Tag tag, AP4_Size header_size, AP4_Size payload_size); - virtual ~AP4_Descriptor() {} - Tag GetTag() { return m_Tag; } - AP4_Size GetSize() { return m_PayloadSize+m_HeaderSize; } - AP4_Size GetHeaderSize() { return m_HeaderSize; } - virtual AP4_Result Write(AP4_ByteStream& stream); - virtual AP4_Result WriteFields(AP4_ByteStream& stream) = 0; - virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + AP4_UI08 GetTag() { return (AP4_UI08)m_ClassId; } +}; - protected: +/*---------------------------------------------------------------------- +| AP4_UnknownDescriptor ++---------------------------------------------------------------------*/ +class AP4_UnknownDescriptor : public AP4_Descriptor +{ +public: + // contrusctor + AP4_UnknownDescriptor(AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size); + + // AP4_Expandable methods + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: // members - Tag m_Tag; - AP4_Size m_HeaderSize; - AP4_Size m_PayloadSize; + AP4_DataBuffer m_Data; }; /*---------------------------------------------------------------------- -| AP4_DescriptorFinder +| AP4_DescriptorFinder +---------------------------------------------------------------------*/ class AP4_DescriptorFinder : public AP4_List<AP4_Descriptor>::Item::Finder { public: - AP4_DescriptorFinder(AP4_Descriptor::Tag tag) : m_Tag(tag) {} + AP4_DescriptorFinder(AP4_UI08 tag) : m_Tag(tag) {} AP4_Result Test(AP4_Descriptor* descriptor) const { return descriptor->GetTag() == m_Tag ? AP4_SUCCESS : AP4_FAILURE; } + private: - AP4_Descriptor::Tag m_Tag; + AP4_UI08 m_Tag; }; /*---------------------------------------------------------------------- -| AP4_DescriptorListWriter +| AP4_DescriptorListWriter +---------------------------------------------------------------------*/ class AP4_DescriptorListWriter : public AP4_List<AP4_Descriptor>::Item::Operator { @@ -97,7 +113,7 @@ private: }; /*---------------------------------------------------------------------- -| AP4_DescriptorListInspector +| AP4_DescriptorListInspector +---------------------------------------------------------------------*/ class AP4_DescriptorListInspector : public AP4_List<AP4_Descriptor>::Item::Operator { diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DescriptorFactory.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DescriptorFactory.cpp index d2ebd8676..331a2bc23 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DescriptorFactory.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DescriptorFactory.cpp @@ -2,7 +2,7 @@ | | AP4 - Descriptor Factory | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,18 +27,19 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4DescriptorFactory.h" #include "Ap4EsDescriptor.h" +#include "Ap4ObjectDescriptor.h" #include "Ap4DecoderConfigDescriptor.h" #include "Ap4DecoderSpecificInfoDescriptor.h" #include "Ap4SLConfigDescriptor.h" -#include "Ap4UnknownDescriptor.h" +#include "Ap4Ipmp.h" +#include "Ap4ByteStream.h" /*---------------------------------------------------------------------- -| AP4_DescriptorFactory::CreateDescriptorFromStream +| AP4_DescriptorFactory::CreateDescriptorFromStream +---------------------------------------------------------------------*/ AP4_Result AP4_DescriptorFactory::CreateDescriptorFromStream(AP4_ByteStream& stream, @@ -50,7 +51,7 @@ AP4_DescriptorFactory::CreateDescriptorFromStream(AP4_ByteStream& stream, descriptor = NULL; // remember current stream offset - AP4_Offset offset; + AP4_Position offset; stream.Tell(offset); // read descriptor tag @@ -78,25 +79,51 @@ AP4_DescriptorFactory::CreateDescriptorFromStream(AP4_ByteStream& stream, // create the descriptor switch (tag) { + case AP4_DESCRIPTOR_TAG_OD: + case AP4_DESCRIPTOR_TAG_MP4_OD: + descriptor = new AP4_ObjectDescriptor(stream, tag, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_IOD: + case AP4_DESCRIPTOR_TAG_MP4_IOD: + descriptor = new AP4_InitialObjectDescriptor(stream, tag, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_ES_ID_INC: + descriptor = new AP4_EsIdIncDescriptor(stream, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_ES_ID_REF: + descriptor = new AP4_EsIdRefDescriptor(stream, header_size, payload_size); + break; + case AP4_DESCRIPTOR_TAG_ES: - descriptor = DNew AP4_EsDescriptor(stream, header_size, payload_size); + descriptor = new AP4_EsDescriptor(stream, header_size, payload_size); break; case AP4_DESCRIPTOR_TAG_DECODER_CONFIG: - descriptor = DNew AP4_DecoderConfigDescriptor(stream, header_size, payload_size); + descriptor = new AP4_DecoderConfigDescriptor(stream, header_size, payload_size); break; case AP4_DESCRIPTOR_TAG_DECODER_SPECIFIC_INFO: - descriptor = DNew AP4_DecoderSpecificInfoDescriptor(stream, header_size, payload_size); + descriptor = new AP4_DecoderSpecificInfoDescriptor(stream, header_size, payload_size); break; case AP4_DESCRIPTOR_TAG_SL_CONFIG: if (payload_size != 1) return AP4_ERROR_INVALID_FORMAT; - descriptor = DNew AP4_SLConfigDescriptor(header_size); + descriptor = new AP4_SLConfigDescriptor(header_size); + break; + + case AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR_POINTER: + descriptor = new AP4_IpmpDescriptorPointer(stream, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR: + descriptor = new AP4_IpmpDescriptor(stream, header_size, payload_size); break; default: - descriptor = DNew AP4_UnknownDescriptor(stream, tag, header_size, payload_size); + descriptor = new AP4_UnknownDescriptor(stream, tag, header_size, payload_size); break; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DescriptorFactory.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DescriptorFactory.h index 2d9ab4264..9fe8bd0c8 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DescriptorFactory.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DescriptorFactory.h @@ -2,7 +2,7 @@ | | AP4 - Descriptor Factory | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,14 +30,18 @@ #define _AP4_DESCRIPTOR_FACTORY_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4Descriptor.h" -#include "Ap4ByteStream.h" +#include "Ap4Types.h" /*---------------------------------------------------------------------- -| AP4_DescriptorFactory +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; +class AP4_Descriptor; + +/*---------------------------------------------------------------------- +| AP4_DescriptorFactory +---------------------------------------------------------------------*/ class AP4_DescriptorFactory { diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DrefAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DrefAtom.cpp index 0157c2969..df83ecc1e 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DrefAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DrefAtom.cpp @@ -1,89 +1,105 @@ -/*****************************************************************
-|
-| AP4 - dref Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4DrefAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-#include "Ap4ContainerAtom.h"
-
-/*----------------------------------------------------------------------
-| AP4_DrefAtom::AP4_DrefAtom
-+---------------------------------------------------------------------*/
-AP4_DrefAtom::AP4_DrefAtom(AP4_Atom** refs, AP4_Cardinal refs_count) :
- AP4_ContainerAtom(AP4_ATOM_TYPE_DREF, AP4_FULL_ATOM_HEADER_SIZE+4, true)
-{
- for (unsigned i=0; i<refs_count; i++) {
- m_Children.Add(refs[i]);
- m_Size += refs[i]->GetSize();
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_DrefAtom::AP4_DrefAtom
-+---------------------------------------------------------------------*/
-AP4_DrefAtom::AP4_DrefAtom(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_ContainerAtom(AP4_ATOM_TYPE_DREF, size, true, stream)
-{
- // read the number of entries
- AP4_UI32 entry_count;
- stream.ReadUI32(entry_count);
-
- // read children
- AP4_Size bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-4;
- while (entry_count--) {
- AP4_Atom* atom;
- while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream,
- bytes_available,
- atom,
- this))) {
- m_Children.Add(atom);
- }
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_DrefAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_DrefAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // write the number of entries
- result = stream.WriteUI32(m_Children.ItemCount());
- if (AP4_FAILED(result)) return result;
-
- // write the children
- return m_Children.Apply(AP4_AtomListWriter(stream));
-}
+/***************************************************************** +| +| AP4 - dref 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 "Ap4DrefAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" +#include "Ap4ContainerAtom.h" + +/*---------------------------------------------------------------------- +| AP4_DrefAtom::Create ++---------------------------------------------------------------------*/ +AP4_DrefAtom* +AP4_DrefAtom::Create(AP4_UI32 size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) +{ + 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_DrefAtom(size, version, flags, stream, atom_factory); +} + +/*---------------------------------------------------------------------- +| AP4_DrefAtom::AP4_DrefAtom ++---------------------------------------------------------------------*/ +AP4_DrefAtom::AP4_DrefAtom(AP4_Atom** refs, AP4_Cardinal refs_count) : + AP4_ContainerAtom(AP4_ATOM_TYPE_DREF, (AP4_UI32)0, (AP4_UI32)0) +{ + m_Size32 += 4; + for (unsigned i=0; i<refs_count; i++) { + m_Children.Add(refs[i]); + m_Size32 += (AP4_UI32)refs[i]->GetSize(); + } +} + +/*---------------------------------------------------------------------- +| AP4_DrefAtom::AP4_DrefAtom ++---------------------------------------------------------------------*/ +AP4_DrefAtom::AP4_DrefAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_ContainerAtom(AP4_ATOM_TYPE_DREF, size, false, version, flags) +{ + // read the number of entries + AP4_UI32 entry_count; + stream.ReadUI32(entry_count); + + // read children + AP4_LargeSize bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-4; + while (entry_count--) { + AP4_Atom* atom; + while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, + bytes_available, + atom))) { + m_Children.Add(atom); + } + } +} + +/*---------------------------------------------------------------------- +| AP4_DrefAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DrefAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // write the number of entries + result = stream.WriteUI32(m_Children.ItemCount()); + if (AP4_FAILED(result)) return result; + + // write the children + return m_Children.Apply(AP4_AtomListWriter(stream)); +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DrefAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DrefAtom.h index 55679f0be..092e959db 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DrefAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DrefAtom.h @@ -2,7 +2,7 @@ | | AP4 - dref Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,27 +30,39 @@ #define _AP4_DREF_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4Array.h" -#include "Ap4Atom.h" -#include "Ap4AtomFactory.h" +#include "Ap4Types.h" #include "Ap4ContainerAtom.h" /*---------------------------------------------------------------------- -| AP4_DrefAtom +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; +class AP4_AtomFactory; + +/*---------------------------------------------------------------------- +| AP4_DrefAtom +---------------------------------------------------------------------*/ class AP4_DrefAtom : public AP4_ContainerAtom { public: + // class methods + static AP4_DrefAtom* Create(AP4_UI32 size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + // methods AP4_DrefAtom(AP4_Atom** refs, AP4_Cardinal refs_count); - AP4_DrefAtom(AP4_Size size, + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // methods + AP4_DrefAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, AP4_ByteStream& stream, AP4_AtomFactory& atom_factory); - virtual AP4_Result WriteFields(AP4_ByteStream& stream); }; #endif // _AP4_DREF_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DynamicCast.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DynamicCast.h new file mode 100644 index 000000000..2bc75d441 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DynamicCast.h @@ -0,0 +1,86 @@ +/***************************************************************** +| +| AP4 - Target Platform and Compiler Configuration +| +| 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 Dynamic Cast Support + */ +#ifndef _AP4_DYNAMIC_CAST_H_ +#define _AP4_DYNAMIC_CAST_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Config.h" + +/*---------------------------------------------------------------------- +| macros ++---------------------------------------------------------------------*/ +#if defined(AP4_CONFIG_NO_RTTI) +#define AP4_DYNAMIC_CAST(_class,_object) \ +( ((_object)==0) ? 0 : reinterpret_cast<_class*>((_object)->DynamicCast(&_class::_class_##_class)) ) +#define AP4_IMPLEMENT_DYNAMIC_CAST(_class) \ +static int _class_##_class; \ +virtual void* DynamicCast(const void* class_anchor) { \ + if (class_anchor == &_class::_class_##_class) { \ + return static_cast<_class*>(this); \ + } \ + return NULL; \ +} +#define AP4_IMPLEMENT_DYNAMIC_CAST_D(_class,_superclass)\ +static int _class_##_class; \ +virtual void* DynamicCast(const void* class_anchor) { \ + if (class_anchor == &_class::_class_##_class) { \ + return static_cast<_class*>(this); \ + } else { \ + return _superclass::DynamicCast(class_anchor); \ + } \ +} +#define AP4_IMPLEMENT_DYNAMIC_CAST_D2(_class,_superclass,_mixin)\ +static int _class_##_class; \ +virtual void* DynamicCast(const void* class_anchor) { \ + if (class_anchor == &_class::_class_##_class) { \ + return static_cast<_class*>(this); \ + } else { \ + void* sup = _superclass::DynamicCast(class_anchor); \ + if (sup) return sup; \ + return _mixin::DynamicCast(class_anchor); \ + } \ +} +#define AP4_DEFINE_DYNAMIC_CAST_ANCHOR(_class) int _class::_class_##_class = 0; + +#else + +#define AP4_DYNAMIC_CAST(_class,_object) dynamic_cast<_class*>(_object) +#define AP4_IMPLEMENT_DYNAMIC_CAST(_class) +#define AP4_IMPLEMENT_DYNAMIC_CAST_D(_class,_superclass) +#define AP4_IMPLEMENT_DYNAMIC_CAST_D2(_class,_superclass,_mixin) +#define AP4_DEFINE_DYNAMIC_CAST_ANCHOR(_class) + +#endif + +#endif // _AP4_DYNAMIC_CAST_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ElstAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ElstAtom.cpp new file mode 100644 index 000000000..73a2c0920 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ElstAtom.cpp @@ -0,0 +1,128 @@ +/***************************************************************** +| +| AP4 - elst 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 "Ap4ElstAtom.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| AP4_ElstAtom::Create ++---------------------------------------------------------------------*/ +AP4_ElstAtom* +AP4_ElstAtom::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 > 1) return NULL; + return new AP4_ElstAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_ElstAtom::AP4_ElstAtom ++---------------------------------------------------------------------*/ +AP4_ElstAtom::AP4_ElstAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_ELST, size, version, flags) +{ + AP4_UI32 entry_count; + stream.ReadUI32(entry_count); + m_Entries.EnsureCapacity(entry_count); + for (AP4_UI32 i=0; i<entry_count; i++) { + AP4_UI16 media_rate; + AP4_UI16 zero; + if (version == 0) { + AP4_UI32 segment_duration; + AP4_UI32 media_time; + stream.ReadUI32(segment_duration); + stream.ReadUI32(media_time); + stream.ReadUI16(media_rate); + stream.ReadUI16(zero); + m_Entries.Append(AP4_ElstEntry(segment_duration, media_time, media_rate)); + } else { + AP4_UI64 segment_duration; + AP4_UI64 media_time; + stream.ReadUI64(segment_duration); + stream.ReadUI64(media_time); + stream.ReadUI16(media_rate); + stream.ReadUI16(zero); + m_Entries.Append(AP4_ElstEntry(segment_duration, media_time, media_rate)); + } + } +} + +/*---------------------------------------------------------------------- +| AP4_ElstAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ElstAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + result = stream.WriteUI32(m_Entries.ItemCount()); + if (AP4_FAILED(result)) return result; + for (AP4_Ordinal i=0; i<m_Entries.ItemCount(); i++) { + if (m_Version == 0) { + result = stream.WriteUI32((AP4_UI32)m_Entries[i].m_SegmentDuration); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32((AP4_UI32)m_Entries[i].m_MediaTime); + if (AP4_FAILED(result)) return result; + } else { + result = stream.WriteUI64(m_Entries[i].m_SegmentDuration); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI64(m_Entries[i].m_MediaTime); + if (AP4_FAILED(result)) return result; + } + result = stream.WriteUI16(m_Entries[i].m_MediaRate); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI16(0); + if (AP4_FAILED(result)) return result; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ElstAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ElstAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("entry count", m_Entries.ItemCount()); + for (AP4_Ordinal i=0; i<m_Entries.ItemCount(); i++) { + inspector.AddField("entry/segment duration", (AP4_UI32)m_Entries[i].m_SegmentDuration); + inspector.AddField("entry/media time", (AP4_SI32)m_Entries[i].m_MediaTime); + inspector.AddField("entry/media rate", (AP4_UI16)m_Entries[i].m_MediaRate); + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ElstAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ElstAtom.h new file mode 100644 index 000000000..d613bf6bd --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ElstAtom.h @@ -0,0 +1,80 @@ +/***************************************************************** +| +| AP4 - elst 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_ELST_ATOM_H_ +#define _AP4_ELST_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" +#include "Ap4Array.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| AP4_ElstAtom ++---------------------------------------------------------------------*/ +class AP4_ElstEntry { +public: + AP4_ElstEntry(AP4_UI64 segment_duration = 0, AP4_SI64 media_time = 0, AP4_UI16 media_rate = 1) : + m_SegmentDuration(segment_duration), + m_MediaTime(media_time), + m_MediaRate(media_rate) {} + + AP4_UI64 m_SegmentDuration; + AP4_SI64 m_MediaTime; + AP4_UI16 m_MediaRate; +}; + +class AP4_ElstAtom : public AP4_Atom +{ +public: + // class methods + static AP4_ElstAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // methods + AP4_ElstAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_Array<AP4_ElstEntry> m_Entries; +}; + +#endif // _AP4_ELST_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsDescriptor.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsDescriptor.cpp index 1d305869b..065d6f513 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsDescriptor.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsDescriptor.cpp @@ -2,7 +2,7 @@ | | AP4 - ES Descriptors | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,15 +27,23 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4EsDescriptor.h" #include "Ap4DescriptorFactory.h" #include "Ap4Utils.h" +#include "Ap4ByteStream.h" +#include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_EsDescriptor::AP4_EsDescriptor +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_EsDescriptor) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_EsIdIncDescriptor) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_EsIdRefDescriptor) + +/*---------------------------------------------------------------------- +| AP4_EsDescriptor::AP4_EsDescriptor +---------------------------------------------------------------------*/ AP4_EsDescriptor::AP4_EsDescriptor(AP4_UI16 es_id) : AP4_Descriptor(AP4_DESCRIPTOR_TAG_ES, 2, 2+1), @@ -48,14 +56,14 @@ AP4_EsDescriptor::AP4_EsDescriptor(AP4_UI16 es_id) : } /*---------------------------------------------------------------------- -| AP4_EsDescriptor::AP4_EsDescriptor +| AP4_EsDescriptor::AP4_EsDescriptor +---------------------------------------------------------------------*/ AP4_EsDescriptor::AP4_EsDescriptor(AP4_ByteStream& stream, AP4_Size header_size, AP4_Size payload_size) : AP4_Descriptor(AP4_DESCRIPTOR_TAG_ES, header_size, payload_size) { - AP4_Offset start; + AP4_Position start; stream.Tell(start); // read descriptor fields @@ -73,9 +81,9 @@ AP4_EsDescriptor::AP4_EsDescriptor(AP4_ByteStream& stream, unsigned char url_length; stream.ReadUI08(url_length); if (url_length) { - char* url = DNew char[url_length+1]; + char* url = new char[url_length+1]; if (url) { - stream.Read(url, url_length, NULL); + stream.Read(url, url_length); url[url_length] = '\0'; m_Url = url; delete[] url; @@ -89,10 +97,10 @@ AP4_EsDescriptor::AP4_EsDescriptor(AP4_ByteStream& stream, } // read other descriptors - AP4_Offset offset; + AP4_Position offset; stream.Tell(offset); - AP4_SubStream* substream = DNew AP4_SubStream(stream, offset, - payload_size-(offset-start)); + AP4_SubStream* substream = new AP4_SubStream(stream, offset, + payload_size-AP4_Size(offset-start)); AP4_Descriptor* descriptor = NULL; while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream, descriptor) @@ -103,7 +111,7 @@ AP4_EsDescriptor::AP4_EsDescriptor(AP4_ByteStream& stream, } /*---------------------------------------------------------------------- -| AP4_EsDescriptor::~AP4_EsDescriptor +| AP4_EsDescriptor::~AP4_EsDescriptor +---------------------------------------------------------------------*/ AP4_EsDescriptor::~AP4_EsDescriptor() { @@ -111,7 +119,7 @@ AP4_EsDescriptor::~AP4_EsDescriptor() } /*---------------------------------------------------------------------- -| AP4_EsDescriptor::WriteFields +| AP4_EsDescriptor::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_EsDescriptor::WriteFields(AP4_ByteStream& stream) @@ -133,9 +141,9 @@ AP4_EsDescriptor::WriteFields(AP4_ByteStream& stream) if (AP4_FAILED(result)) return result; } if (m_Flags & AP4_ES_DESCRIPTOR_FLAG_URL) { - result = stream.WriteUI08(m_Url.length()); + result = stream.WriteUI08((AP4_UI08)m_Url.GetLength()); if (AP4_FAILED(result)) return result; - result = stream.WriteString(m_Url.c_str()); + result = stream.WriteString(m_Url.GetChars()); if (AP4_FAILED(result)) return result; result = stream.WriteUI08(0); if (AP4_FAILED(result)) return result; @@ -152,15 +160,15 @@ AP4_EsDescriptor::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_EsDescriptor::Inspect +| AP4_EsDescriptor::Inspect +---------------------------------------------------------------------*/ AP4_Result AP4_EsDescriptor::Inspect(AP4_AtomInspector& inspector) { char info[64]; - AP4_StringFormat(info, sizeof(info), "size=%ld+%ld", + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", GetHeaderSize(),m_PayloadSize); - inspector.StartElement("#[ES]", info); + inspector.StartElement("[ESDescriptor]", info); inspector.AddField("es_id", m_EsId); inspector.AddField("stream_priority", m_StreamPriority); @@ -173,7 +181,7 @@ AP4_EsDescriptor::Inspect(AP4_AtomInspector& inspector) } /*---------------------------------------------------------------------- -| AP4_EsDescriptor::AddSubDescriptor +| AP4_EsDescriptor::AddSubDescriptor +---------------------------------------------------------------------*/ AP4_Result AP4_EsDescriptor::AddSubDescriptor(AP4_Descriptor* descriptor) @@ -185,7 +193,7 @@ AP4_EsDescriptor::AddSubDescriptor(AP4_Descriptor* descriptor) } /*---------------------------------------------------------------------- -| AP4_EsDescriptor::GetDecoderConfigDescriptor +| AP4_EsDescriptor::GetDecoderConfigDescriptor +---------------------------------------------------------------------*/ const AP4_DecoderConfigDescriptor* AP4_EsDescriptor::GetDecoderConfigDescriptor() const @@ -198,8 +206,102 @@ AP4_EsDescriptor::GetDecoderConfigDescriptor() const // return it if (AP4_SUCCEEDED(result)) { - return dynamic_cast<AP4_DecoderConfigDescriptor*>(descriptor); + return AP4_DYNAMIC_CAST(AP4_DecoderConfigDescriptor, descriptor); } else { return NULL; } } + +/*---------------------------------------------------------------------- +| AP4_EsIdIncDescriptor::AP4_EsIdIncDescriptor ++---------------------------------------------------------------------*/ +AP4_EsIdIncDescriptor::AP4_EsIdIncDescriptor(AP4_UI32 track_id) : + AP4_Descriptor(AP4_DESCRIPTOR_TAG_ES_ID_INC, 2, 4), + m_TrackId(track_id) +{ +} + +/*---------------------------------------------------------------------- +| AP4_EsIdIncDescriptor::AP4_EsIdIncDescriptor ++---------------------------------------------------------------------*/ +AP4_EsIdIncDescriptor::AP4_EsIdIncDescriptor(AP4_ByteStream& stream, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_Descriptor(AP4_DESCRIPTOR_TAG_ES_ID_INC, header_size, payload_size) +{ + // read the track id + stream.ReadUI32(m_TrackId); +} + +/*---------------------------------------------------------------------- +| AP4_EsIdIncescriptor::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EsIdIncDescriptor::WriteFields(AP4_ByteStream& stream) +{ + // track id + return stream.WriteUI32(m_TrackId); +} + +/*---------------------------------------------------------------------- +| AP4_EsIdIncDescriptor::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EsIdIncDescriptor::Inspect(AP4_AtomInspector& inspector) +{ + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(),m_PayloadSize); + inspector.StartElement("[ES_ID_Inc]", info); + inspector.AddField("track_id", m_TrackId); + inspector.EndElement(); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_EsIdRefDescriptor::AP4_EsIdRefDescriptor ++---------------------------------------------------------------------*/ +AP4_EsIdRefDescriptor::AP4_EsIdRefDescriptor(AP4_UI16 ref_index) : + AP4_Descriptor(AP4_DESCRIPTOR_TAG_ES_ID_REF, 2, 2), + m_RefIndex(ref_index) +{ +} + +/*---------------------------------------------------------------------- +| AP4_EsIdRefDescriptor::AP4_EsIdRefDescriptor ++---------------------------------------------------------------------*/ +AP4_EsIdRefDescriptor::AP4_EsIdRefDescriptor(AP4_ByteStream& stream, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_Descriptor(AP4_DESCRIPTOR_TAG_ES_ID_REF, header_size, payload_size) +{ + // read the ref index + stream.ReadUI16(m_RefIndex); +} + +/*---------------------------------------------------------------------- +| AP4_EsIdRefDescriptor::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EsIdRefDescriptor::WriteFields(AP4_ByteStream& stream) +{ + // ref index + return stream.WriteUI16(m_RefIndex); +} + +/*---------------------------------------------------------------------- +| AP4_EsIdRefDescriptor::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_EsIdRefDescriptor::Inspect(AP4_AtomInspector& inspector) +{ + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(),m_PayloadSize); + inspector.StartElement("[ES_ID_Ref]", info); + inspector.AddField("ref_index", m_RefIndex); + inspector.EndElement(); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsDescriptor.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsDescriptor.h index e52b67d1d..d971e7e05 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsDescriptor.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsDescriptor.h @@ -2,7 +2,7 @@ | | AP4 - ES Descriptor | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,29 +30,37 @@ #define _AP4_ES_DESCRIPTOR_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" #include "Ap4List.h" +#include "Ap4String.h" #include "Ap4Descriptor.h" #include "Ap4DecoderConfigDescriptor.h" /*---------------------------------------------------------------------- -| constants +| class references +---------------------------------------------------------------------*/ -const AP4_Descriptor::Tag AP4_DESCRIPTOR_TAG_ES = 0x03; +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI08 AP4_DESCRIPTOR_TAG_ES = 0x03; +const AP4_UI08 AP4_DESCRIPTOR_TAG_ES_ID_INC = 0x0E; +const AP4_UI08 AP4_DESCRIPTOR_TAG_ES_ID_REF = 0x0F; const int AP4_ES_DESCRIPTOR_FLAG_STREAM_DEPENDENCY = 1; const int AP4_ES_DESCRIPTOR_FLAG_URL = 2; const int AP4_ES_DESCRIPTOR_FLAG_OCR_STREAM = 4; /*---------------------------------------------------------------------- -| AP4_EsDescriptor +| AP4_EsDescriptor +---------------------------------------------------------------------*/ class AP4_EsDescriptor : public AP4_Descriptor { public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_EsDescriptor, AP4_Descriptor) + // methods AP4_EsDescriptor(AP4_UI16 es_id); AP4_EsDescriptor(AP4_ByteStream& stream, @@ -75,4 +83,52 @@ class AP4_EsDescriptor : public AP4_Descriptor mutable AP4_List<AP4_Descriptor> m_SubDescriptors; }; +/*---------------------------------------------------------------------- +| AP4_EsIdIncDescriptor ++---------------------------------------------------------------------*/ +class AP4_EsIdIncDescriptor : public AP4_Descriptor +{ + public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_EsIdIncDescriptor, AP4_Descriptor) + + // methods + AP4_EsIdIncDescriptor(AP4_UI32 track_id); + AP4_EsIdIncDescriptor(AP4_ByteStream& stream, + AP4_Size header_size, + AP4_Size payload_size); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + + // accessors + AP4_UI32 GetTrackId() const { return m_TrackId; } + + private: + // members + AP4_UI32 m_TrackId; +}; + +/*---------------------------------------------------------------------- +| AP4_EsIdRefDescriptor ++---------------------------------------------------------------------*/ +class AP4_EsIdRefDescriptor : public AP4_Descriptor +{ + public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_EsIdRefDescriptor, AP4_Descriptor) + + // methods + AP4_EsIdRefDescriptor(AP4_UI16 ref_index); + AP4_EsIdRefDescriptor(AP4_ByteStream& stream, + AP4_Size header_size, + AP4_Size payload_size); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + + // accessors + AP4_UI16 GetRefIndex() const { return m_RefIndex; } + + private: + // members + AP4_UI16 m_RefIndex; +}; + #endif // _AP4_ES_DESCRIPTOR_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsdsAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsdsAtom.cpp index 7be18b6f8..b03e73a91 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsdsAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsdsAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - esds Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,41 +27,61 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4EsdsAtom.h" #include "Ap4DescriptorFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_EsdsAtom::AP4_EsdsAtom +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_EsdsAtom) + +/*---------------------------------------------------------------------- +| AP4_EsdsAtom::Create ++---------------------------------------------------------------------*/ +AP4_EsdsAtom* +AP4_EsdsAtom::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_EsdsAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_EsdsAtom::AP4_EsdsAtom +---------------------------------------------------------------------*/ AP4_EsdsAtom::AP4_EsdsAtom(AP4_EsDescriptor* descriptor) : - AP4_Atom(AP4_ATOM_TYPE_ESDS, AP4_FULL_ATOM_HEADER_SIZE, true), + AP4_Atom(AP4_ATOM_TYPE_ESDS, AP4_FULL_ATOM_HEADER_SIZE, 0, 0), m_EsDescriptor(descriptor) { - if (m_EsDescriptor) m_Size += m_EsDescriptor->GetSize(); + if (m_EsDescriptor) m_Size32 += m_EsDescriptor->GetSize(); } /*---------------------------------------------------------------------- -| AP4_EsdsAtom::AP4_EsdsAtom +| AP4_EsdsAtom::AP4_EsdsAtom +---------------------------------------------------------------------*/ -AP4_EsdsAtom::AP4_EsdsAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_ESDS, size, true, stream) +AP4_EsdsAtom::AP4_EsdsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_ESDS, size, version, flags) { // read descriptor AP4_Descriptor* descriptor = NULL; if (AP4_DescriptorFactory::CreateDescriptorFromStream(stream, descriptor) == AP4_SUCCESS) { - m_EsDescriptor = dynamic_cast<AP4_EsDescriptor*>(descriptor); + m_EsDescriptor = AP4_DYNAMIC_CAST(AP4_EsDescriptor, descriptor); } else { m_EsDescriptor = NULL; } } /*---------------------------------------------------------------------- -| AP4_EsdsAtom::~AP4_EsdsAtom +| AP4_EsdsAtom::~AP4_EsdsAtom +---------------------------------------------------------------------*/ AP4_EsdsAtom::~AP4_EsdsAtom() { @@ -69,7 +89,7 @@ AP4_EsdsAtom::~AP4_EsdsAtom() } /*---------------------------------------------------------------------- -| AP4_EsdsAtom::WriteFields +| AP4_EsdsAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_EsdsAtom::WriteFields(AP4_ByteStream& stream) @@ -81,7 +101,7 @@ AP4_EsdsAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_EsdsAtom::InspectFields +| AP4_EsdsAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_EsdsAtom::InspectFields(AP4_AtomInspector& inspector) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsdsAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsdsAtom.h index 2e3a114cd..962f9e2c3 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsdsAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4EsdsAtom.h @@ -2,7 +2,7 @@ | | AP4 - esds Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,30 +30,42 @@ #define _AP4_ESDS_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4List.h" +#include "Ap4Types.h" #include "Ap4Atom.h" #include "Ap4EsDescriptor.h" -#include "Ap4AtomFactory.h" /*---------------------------------------------------------------------- -| AP4_EsdsAtom +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| AP4_EsdsAtom +---------------------------------------------------------------------*/ class AP4_EsdsAtom : public AP4_Atom { - public: +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_EsdsAtom, AP4_Atom) + + // class methods + static AP4_EsdsAtom* Create(AP4_Size size, AP4_ByteStream& stream); + // methods AP4_EsdsAtom(AP4_EsDescriptor* descriptor); - AP4_EsdsAtom(AP4_Size size, AP4_ByteStream& stream); ~AP4_EsdsAtom(); virtual AP4_Result WriteFields(AP4_ByteStream& stream); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); const AP4_EsDescriptor* GetEsDescriptor() const { return m_EsDescriptor; } - private: +private: + // methods + AP4_EsdsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + // members AP4_EsDescriptor* m_EsDescriptor; }; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Expandable.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Expandable.cpp new file mode 100644 index 000000000..a0fa39601 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Expandable.cpp @@ -0,0 +1,126 @@ +/***************************************************************** +| +| AP4 - Expandable base class +| +| 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 "Ap4Debug.h" +#include "Ap4Descriptor.h" +#include "Ap4Utils.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_Expandable::MinHeaderSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_Expandable::MinHeaderSize(AP4_Size payload_size) +{ + // compute how many bytes are needed to encode the payload size + // plus tag + return 2+(payload_size/128); +} + +/*---------------------------------------------------------------------- +| AP4_Expandable::AP4_Expandable ++---------------------------------------------------------------------*/ +AP4_Expandable::AP4_Expandable(AP4_UI32 class_id, + ClassIdSize class_id_size, + AP4_Size header_size, + AP4_Size payload_size) : + m_ClassId(class_id), + m_ClassIdSize(class_id_size), + m_HeaderSize(header_size), + m_PayloadSize(payload_size) +{ + AP4_ASSERT(header_size >= 1+1); + AP4_ASSERT(header_size <= 1+4); +} + +/*---------------------------------------------------------------------- +| AP4_Expandable::Write ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Expandable::Write(AP4_ByteStream& stream) +{ + AP4_Result result; + + // write the class id + switch (m_ClassIdSize) { + case CLASS_ID_SIZE_08: + result = stream.WriteUI08((AP4_UI08)m_ClassId); + if (AP4_FAILED(result)) return result; + break; + + default: + return AP4_ERROR_INTERNAL; + } + + // write the size + AP4_ASSERT(m_HeaderSize-1 <= 8); + AP4_ASSERT(m_HeaderSize >= 2); + unsigned int size = m_PayloadSize; + unsigned char bytes[8]; + + // last bytes of the encoded size + bytes[m_HeaderSize-2] = size&0x7F; + + // leading bytes of the encoded size + for (int i=m_HeaderSize-3; i>=0; i--) { + // move to the next 7 bits + size >>= 7; + + // output a byte with a top bit marker + bytes[i] = (size&0x7F) | 0x80; + } + + result = stream.Write(bytes, m_HeaderSize-1); + if (AP4_FAILED(result)) return result; + + // write the fields + WriteFields(stream); + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_Expandable::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Expandable::Inspect(AP4_AtomInspector& inspector) +{ + char name[6]; + AP4_FormatString(name, sizeof(name), "[#:%02x]", m_ClassId); + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(), + m_PayloadSize); + inspector.StartElement(name, info); + inspector.EndElement(); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Expandable.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Expandable.h new file mode 100644 index 000000000..63949eeb5 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Expandable.h @@ -0,0 +1,98 @@ +/***************************************************************** +| +| AP4 - Expandable base class +| +| 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_EXPANDABLE_H_ +#define _AP4_EXPANDABLE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4DataBuffer.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; +class AP4_AtomInspector; + +/*---------------------------------------------------------------------- +| AP4_Expandable ++---------------------------------------------------------------------*/ +class AP4_Expandable +{ + public: + // types + enum ClassIdSize { + CLASS_ID_SIZE_08 + }; + + // class methods + static AP4_Size MinHeaderSize(AP4_Size payload_size); + + // methods + AP4_Expandable(AP4_UI32 class_id, + ClassIdSize class_id_size, + AP4_Size header_size, + AP4_Size payload_size); + virtual ~AP4_Expandable() {} + AP4_UI32 GetClassId() { return m_ClassId; } + AP4_Size GetSize() { return m_PayloadSize+m_HeaderSize; } + AP4_Size GetHeaderSize() { return m_HeaderSize; } + virtual AP4_Result Write(AP4_ByteStream& stream); + virtual AP4_Result WriteFields(AP4_ByteStream& stream) = 0; + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + + protected: + // members + AP4_UI32 m_ClassId; + ClassIdSize m_ClassIdSize; + AP4_Size m_HeaderSize; + AP4_Size m_PayloadSize; +}; + +/*---------------------------------------------------------------------- +| AP4_UnknownExpandable ++---------------------------------------------------------------------*/ +class AP4_UnknownExpandable : public AP4_Expandable +{ +public: + // methods + AP4_UnknownExpandable(AP4_ByteStream& stream, + AP4_UI32 class_id, + ClassIdSize class_id_size, + AP4_Size header_size, + AP4_Size payload_size); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // members + AP4_DataBuffer m_Data; +}; + +#endif // _AP4_EXPANDABLE_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4File.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4File.cpp index 995bc4a72..9852e33f7 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4File.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4File.cpp @@ -1,90 +1,144 @@ -/*****************************************************************
-|
-| AP4 - File
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4File.h"
-#include "Ap4Atom.h"
-#include "Ap4TrakAtom.h"
-#include "Ap4MoovAtom.h"
-#include "Ap4MvhdAtom.h"
-#include "Ap4AtomFactory.h"
-
-/*----------------------------------------------------------------------
-| AP4_File::AP4_File
-+---------------------------------------------------------------------*/
-AP4_File::AP4_File(AP4_Movie* movie) :
- m_Movie(movie)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_File::AP4_File
-+---------------------------------------------------------------------*/
-AP4_File::AP4_File(AP4_ByteStream& stream, AP4_AtomFactory& atom_factory) :
- m_Movie(NULL)
-{
- // get all atoms
- AP4_Atom* atom;
- while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, atom))) {
- switch (atom->GetType()) {
- case AP4_ATOM_TYPE_MOOV:
- m_Movie = DNew AP4_Movie(dynamic_cast<AP4_MoovAtom*>(atom),
- stream);
- break;
-
- default:
- m_OtherAtoms.Add(atom);
- }
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_File::~AP4_File
-+---------------------------------------------------------------------*/
-AP4_File::~AP4_File()
-{
- delete m_Movie;
- m_OtherAtoms.DeleteReferences();
-}
-
-/*----------------------------------------------------------------------
-| AP4_File::Inspect
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_File::Inspect(AP4_AtomInspector& inspector)
-{
- // dump the moov atom first
- if (m_Movie) m_Movie->Inspect(inspector);
-
- // dump the other atoms
- m_OtherAtoms.Apply(AP4_AtomListInspector(inspector));
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - File +| +| 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 "Ap4File.h" +#include "Ap4Atom.h" +#include "Ap4TrakAtom.h" +#include "Ap4MoovAtom.h" +#include "Ap4MvhdAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Movie.h" +#include "Ap4FtypAtom.h" +#include "Ap4MetaData.h" + +/*---------------------------------------------------------------------- +| AP4_File::AP4_File ++---------------------------------------------------------------------*/ +AP4_File::AP4_File(AP4_Movie* movie) : + m_Movie(movie), + m_FileType(NULL), + m_MetaData(NULL), + m_MoovIsBeforeMdat(true) +{ +} + +/*---------------------------------------------------------------------- +| AP4_File::AP4_File ++---------------------------------------------------------------------*/ +AP4_File::AP4_File(AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory, + bool moov_only) : + m_Movie(NULL), + m_FileType(NULL), + m_MetaData(NULL), + m_MoovIsBeforeMdat(true) +{ + // parse top-level atoms + AP4_Atom* atom; + AP4_Position stream_position; + bool keep_parsing = true; + while (keep_parsing && + AP4_SUCCEEDED(stream.Tell(stream_position)) && + AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, atom))) { + AddChild(atom); + switch (atom->GetType()) { + case AP4_ATOM_TYPE_MOOV: + m_Movie = new AP4_Movie(AP4_DYNAMIC_CAST(AP4_MoovAtom, atom), stream, false); + if (moov_only) keep_parsing = false; + break; + + case AP4_ATOM_TYPE_FTYP: + m_FileType = AP4_DYNAMIC_CAST(AP4_FtypAtom, atom); + break; + + case AP4_ATOM_TYPE_MDAT: + // see if we are before the moov atom + if (m_Movie == NULL) m_MoovIsBeforeMdat = false; + break; + } + } +} + +/*---------------------------------------------------------------------- +| AP4_File::~AP4_File ++---------------------------------------------------------------------*/ +AP4_File::~AP4_File() +{ + delete m_Movie; + delete m_MetaData; +} + +/*---------------------------------------------------------------------- +| AP4_File::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_File::Inspect(AP4_AtomInspector& inspector) +{ + // dump the moov atom first + if (m_Movie) m_Movie->Inspect(inspector); + + // dump the other atoms + m_Children.Apply(AP4_AtomListInspector(inspector)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_File::SetFileType ++---------------------------------------------------------------------*/ +AP4_Result +AP4_File::SetFileType(AP4_UI32 major_brand, + AP4_UI32 minor_version, + AP4_UI32* compatible_brands, + AP4_Cardinal compatible_brand_count) +{ + delete m_FileType; + m_FileType = new AP4_FtypAtom(major_brand, + minor_version, + compatible_brands, + compatible_brand_count); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_File::GetMetaData ++---------------------------------------------------------------------*/ +const AP4_MetaData* +AP4_File::GetMetaData() +{ + if (m_MetaData == NULL) { + m_MetaData = new AP4_MetaData(this); + } + + return m_MetaData; +} + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4File.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4File.h index 6e091bd43..180c31819 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4File.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4File.h @@ -2,7 +2,7 @@ | | AP4 - File | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,36 +30,119 @@ #define _AP4_FILE_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4Atom.h" -#include "Ap4Track.h" +#include "Ap4Types.h" #include "Ap4List.h" -#include "Ap4Movie.h" -#include "Ap4ByteStream.h" +#include "Ap4Atom.h" #include "Ap4AtomFactory.h" /*---------------------------------------------------------------------- -| AP4_File +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; +class AP4_Movie; +class AP4_FtypAtom; +class AP4_MetaData; + +/*---------------------------------------------------------------------- +| file type/brands ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_FILE_BRAND_QT__ = AP4_ATOM_TYPE('q','t',' ',' '); +const AP4_UI32 AP4_FILE_BRAND_ISOM = AP4_ATOM_TYPE('i','s','o','m'); +const AP4_UI32 AP4_FILE_BRAND_MP41 = AP4_ATOM_TYPE('m','p','4','1'); +const AP4_UI32 AP4_FILE_BRAND_MP42 = AP4_ATOM_TYPE('m','p','4','2'); +const AP4_UI32 AP4_FILE_BRAND_3GP1 = AP4_ATOM_TYPE('3','g','p','1'); +const AP4_UI32 AP4_FILE_BRAND_3GP2 = AP4_ATOM_TYPE('3','g','p','2'); +const AP4_UI32 AP4_FILE_BRAND_3GP3 = AP4_ATOM_TYPE('3','g','p','3'); +const AP4_UI32 AP4_FILE_BRAND_3GP4 = AP4_ATOM_TYPE('3','g','p','4'); +const AP4_UI32 AP4_FILE_BRAND_3GP5 = AP4_ATOM_TYPE('3','g','p','5'); +const AP4_UI32 AP4_FILE_BRAND_3G2A = AP4_ATOM_TYPE('3','g','2','a'); +const AP4_UI32 AP4_FILE_BRAND_MMP4 = AP4_ATOM_TYPE('m','m','p','4'); +const AP4_UI32 AP4_FILE_BRAND_M4A_ = AP4_ATOM_TYPE('M','4','A',' '); +const AP4_UI32 AP4_FILE_BRAND_M4P_ = AP4_ATOM_TYPE('M','4','P',' '); +const AP4_UI32 AP4_FILE_BRAND_MJP2 = AP4_ATOM_TYPE('m','j','p','2'); + +/*---------------------------------------------------------------------- +| AP4_File +---------------------------------------------------------------------*/ -class AP4_File { + +/** + * The AP4_File object is the top level object for MP4 Files. + */ + +class AP4_File : public AP4_AtomParent { public: // constructors and destructor - AP4_File(AP4_Movie* movie); - AP4_File(AP4_ByteStream& stream, - AP4_AtomFactory& atom_factory = AP4_AtomFactory::DefaultFactory); + /** + * Constructs an AP4_File from an AP4_Movie (used for writing) + * @param movie the movie + */ + AP4_File(AP4_Movie* movie = NULL); + + /** + * Constructs an AP4_File from a stream + * @param stream the stream containing the data of the file + * @param factory the atom factory that will be used to parse the stream + * @param moov_only indicates whether parsing of the atoms should stop + * when the moov atom is found or if all atoms should be parsed until the + * end of the file. + */ + AP4_File(AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory = AP4_DefaultAtomFactory::Instance, + bool moov_only = false); + + /** + * Destroys the AP4_File instance + */ virtual ~AP4_File(); + + /** + * Get the top level atoms of the file + */ + AP4_List<AP4_Atom>& GetTopLevelAtoms() { return m_Children; } + + /** + * Get the AP4_Movie object of this file + */ + AP4_Movie* GetMovie() { return m_Movie; } + + + /** + * Get the file type atom of this file + */ + AP4_FtypAtom* GetFileType() { return m_FileType; } + + /** + * Set the file type. Will internally create an AP4_Ftyp atom + * and attach it to the file + */ + AP4_Result SetFileType(AP4_UI32 major_brand, + AP4_UI32 minor_version, + AP4_UI32* compatible_brands = NULL, + AP4_Cardinal compatible_brand_count = 0); - // methods - AP4_List<AP4_Atom>& GetOtherAtoms() { return m_OtherAtoms;} - AP4_Movie* GetMovie() { return m_Movie; } + /** + * Ask whether the moov atom appears before the first mdat atom + */ + bool IsMoovBeforeMdat() const { return m_MoovIsBeforeMdat; } + + /** + * Get the file's metadata description + */ + const AP4_MetaData* GetMetaData(); + + /** + * Inspect the content of the file with an AP4_AtomInspector + */ virtual AP4_Result Inspect(AP4_AtomInspector& inspector); private: // members - AP4_Movie* m_Movie; - AP4_List<AP4_Atom> m_OtherAtoms; + AP4_Movie* m_Movie; + AP4_FtypAtom* m_FileType; + AP4_MetaData* m_MetaData; + bool m_MoovIsBeforeMdat; }; #endif // _AP4_FILE_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileByteStream.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileByteStream.h index 564813597..f7d82706e 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileByteStream.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileByteStream.h @@ -2,7 +2,7 @@ | | AP4 - FileByteStream | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,43 +27,65 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" +#include "Ap4Types.h" #include "Ap4ByteStream.h" +#include "Ap4Config.h" #ifndef _AP4_FILE_BYTE_STREAM_H_ #define _AP4_FILE_BYTE_STREAM_H_ /*---------------------------------------------------------------------- -| AP4_FileByteStream +| AP4_FileByteStream +---------------------------------------------------------------------*/ class AP4_FileByteStream: public AP4_ByteStream { public: // types typedef enum { - STREAM_MODE_READ, - STREAM_MODE_WRITE + STREAM_MODE_READ = 0, + STREAM_MODE_WRITE = 1, + STREAM_MODE_READ_WRITE = 2 } Mode; - // methods + /** + * Create a stream from a file (opened or created). + * + * @param name Name of the file open or create + * @param mode Mode to use for the file + * @param stream Refrence to a pointer where the stream object will + * be returned + * @return AP4_SUCCESS if the file can be opened or created, or an error code if + * it cannot + */ + static AP4_Result Create(const char* name, Mode mode, AP4_ByteStream*& stream); + + // constructors + AP4_FileByteStream(AP4_ByteStream* delegate) : m_Delegate(delegate) {} + +#if !defined(AP4_CONFIG_NO_EXCEPTIONS) + /** + * @deprecated + */ AP4_FileByteStream(const char* name, Mode mode); +#endif // AP4_ByteStream methods - AP4_Result Read(void* buffer, - AP4_Size bytesToRead, - AP4_Size* bytesRead) { - return m_Delegate->Read(buffer, bytesToRead, bytesRead); + AP4_Result ReadPartial(void* buffer, + AP4_Size bytesToRead, + AP4_Size& bytesRead) { + return m_Delegate->ReadPartial(buffer, bytesToRead, bytesRead); } - AP4_Result Write(const void* buffer, - AP4_Size bytesToWrite, - AP4_Size* bytesWritten) { - return m_Delegate->Write(buffer, bytesToWrite, bytesWritten); + AP4_Result WritePartial(const void* buffer, + AP4_Size bytesToWrite, + AP4_Size& bytesWritten) { + return m_Delegate->WritePartial(buffer, bytesToWrite, bytesWritten); } - AP4_Result Seek(AP4_Offset offset) { return m_Delegate->Seek(offset); } - AP4_Result Tell(AP4_Offset& offset) { return m_Delegate->Tell(offset); } - AP4_Result GetSize(AP4_Size& size) { return m_Delegate->GetSize(size);} + AP4_Result Seek(AP4_Position position) { return m_Delegate->Seek(position); } + AP4_Result Tell(AP4_Position& position) { return m_Delegate->Tell(position); } + AP4_Result GetSize(AP4_LargeSize& size) { return m_Delegate->GetSize(size); } + AP4_Result Flush() { return m_Delegate->Flush(); } // AP4_Referenceable methods void AddReference() { m_Delegate->AddReference(); } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DcomAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileCopier.cpp index 12878c43c..626763539 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DcomAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileCopier.cpp @@ -1,46 +1,53 @@ -/*****************************************************************
-|
-| AP4 - dcom Atom
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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 "Ap4DcomAtom.h"
-
-/*----------------------------------------------------------------------
-| AP4_DcomAtom::AP4_DcomAtom
-+---------------------------------------------------------------------*/
-
-AP4_DcomAtom::AP4_DcomAtom(AP4_Size size,
- AP4_ByteStream& stream)
- : AP4_Atom(AP4_ATOM_TYPE_DCOM)
-{
- size -= AP4_ATOM_HEADER_SIZE;
-
- stream.ReadUI32(m_CompressorSubType);
-}
+/***************************************************************** +| +| AP4 - File Copier +| +| 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 "Ap4MoovAtom.h" +#include "Ap4FileCopier.h" +#include "Ap4Movie.h" +#include "Ap4File.h" +#include "Ap4FtypAtom.h" + +/*---------------------------------------------------------------------- +| AP4_FileCopier::Write ++---------------------------------------------------------------------*/ +AP4_Result +AP4_FileCopier::Write(AP4_File& file, AP4_ByteStream& stream) +{ + // write the top-level atoms + for (AP4_List<AP4_Atom>::Item* item = file.GetTopLevelAtoms().FirstItem(); + item; + item = item->GetNext()) { + AP4_Atom* atom = item->GetData(); + atom->Write(stream); + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DcomAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileCopier.h index 541bb3bfa..320177eaf 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4DcomAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileCopier.h @@ -1,55 +1,56 @@ -/*****************************************************************
-|
-| AP4 - dcom Atom
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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_DCOM_ATOM_H_
-#define _AP4_DCOM_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4Atom.h"
-#include "Ap4Types.h"
-
-/*----------------------------------------------------------------------
-| AP4_DcomAtom
-+---------------------------------------------------------------------*/
-class AP4_DcomAtom : public AP4_Atom
-{
-public:
- AP4_DcomAtom(AP4_Size size,
- AP4_ByteStream& stream);
-
- AP4_Result WriteFields(AP4_ByteStream& stream) { return AP4_FAILURE; }
-
- AP4_Atom::Type GetCompressorSubType() const { return m_CompressorSubType; }
-
-private:
- AP4_Atom::Type m_CompressorSubType;
-};
-
-#endif // _AP4_DCOM_ATOM_H_
+/***************************************************************** +| +| AP4 - File Writer +| +| 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_FILE_COPIER_H_ +#define _AP4_FILE_COPIER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; +class AP4_File; + +/*---------------------------------------------------------------------- +| AP4_FileCopier ++---------------------------------------------------------------------*/ +class AP4_FileCopier { +public: + // class methods + static AP4_Result Write(AP4_File& file, AP4_ByteStream& stream); + +private: + // don't instantiate this class + AP4_FileCopier() {}; +}; + +#endif // _AP4_FILE_COPIER_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileWriter.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileWriter.cpp index 663fe9286..c7e8090cc 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileWriter.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileWriter.cpp @@ -2,7 +2,7 @@ | | AP4 - File Writer | -| Copyright 2002-2005 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,64 +27,124 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4MoovAtom.h" #include "Ap4FileWriter.h" +#include "Ap4Movie.h" +#include "Ap4File.h" +#include "Ap4TrakAtom.h" +#include "Ap4Track.h" +#include "Ap4Sample.h" +#include "Ap4DataBuffer.h" +#include "Ap4FtypAtom.h" +#include "Ap4SampleTable.h" /*---------------------------------------------------------------------- -| AP4_FileWriter::AP4_FileWriter -+---------------------------------------------------------------------*/ -AP4_FileWriter::AP4_FileWriter(AP4_File& file) : m_File(file) -{ -} - -/*---------------------------------------------------------------------- -| AP4_FileWriter::~AP4_FileWriter -+---------------------------------------------------------------------*/ -AP4_FileWriter::~AP4_FileWriter() -{ -} - -/*---------------------------------------------------------------------- -| AP4_FileWriter::Write +| AP4_FileWriter::Write +---------------------------------------------------------------------*/ AP4_Result -AP4_FileWriter::Write(AP4_ByteStream& stream) +AP4_FileWriter::Write(AP4_File& file, AP4_ByteStream& stream, Interleaving /* interleaving */) { - //AP4_Result result; + // get the file type + AP4_FtypAtom* file_type = file.GetFileType(); - // get the movie object - AP4_Movie* movie = m_File.GetMovie(); + // write the ftyp atom (always first) + if (file_type) file_type->Write(stream); + + // write the top-level atoms, except for ftyp, moov and mdat + for (AP4_List<AP4_Atom>::Item* atom_item = file.GetChildren().FirstItem(); + atom_item; + atom_item = atom_item->GetNext()) { + AP4_Atom* atom = atom_item->GetData(); + if (atom->GetType() != AP4_ATOM_TYPE_MDAT && + atom->GetType() != AP4_ATOM_TYPE_FTYP && + atom->GetType() != AP4_ATOM_TYPE_MOOV) { + atom->Write(stream); + } + } + + // get the movie object (and stop if there isn't any) + AP4_Movie* movie = file.GetMovie(); if (movie == NULL) return AP4_SUCCESS; - // compute the final offset of the sample data in mdat - AP4_Offset data_offset = movie->GetMoovAtom()->GetSize()+AP4_ATOM_HEADER_SIZE; + // see how much we've written so far + AP4_Position position; + stream.Tell(position); + + // backup and recompute all the chunk offsets + unsigned int t=0; + AP4_Result result = AP4_SUCCESS; + AP4_UI64 mdat_size = AP4_ATOM_HEADER_SIZE; + AP4_UI64 mdat_position = position+movie->GetMoovAtom()->GetSize(); + AP4_Array<AP4_Array<AP4_UI64>*> trak_chunk_offsets_backup; + AP4_Array<AP4_UI64> chunk_offsets; + for (AP4_List<AP4_Track>::Item* track_item = movie->GetTracks().FirstItem(); + track_item; + track_item = track_item->GetNext()) { + AP4_Track* track = track_item->GetData(); + AP4_TrakAtom* trak = track->GetTrakAtom(); + + // backup the chunk offsets + AP4_Array<AP4_UI64>* chunk_offsets_backup = new AP4_Array<AP4_UI64>(); + trak_chunk_offsets_backup.Append(chunk_offsets_backup); + result = trak->GetChunkOffsets(*chunk_offsets_backup); + if (AP4_FAILED(result)) goto end; - // adjust the tracks - AP4_List<AP4_Track>::Item* track_item = movie->GetTracks().FirstItem(); - while (track_item) { - AP4_Track* track = track_item->GetData(); - track->GetTrakAtom()->AdjustChunkOffsets(data_offset); - track_item = track_item->GetNext(); + // allocate space for the new chunk offsets + chunk_offsets.SetItemCount(chunk_offsets_backup->ItemCount()); + + // compute the new chunk offsets + AP4_Cardinal sample_count = track->GetSampleCount(); + AP4_SampleTable* sample_table = track->GetSampleTable(); + AP4_Sample sample; + for (AP4_Ordinal i=0; i<sample_count; i++) { + AP4_Ordinal chunk_index = 0; + AP4_Ordinal position_in_chunk = 0; + sample_table->GetSampleChunkPosition(i, chunk_index, position_in_chunk); + sample_table->GetSample(i, sample); + if (position_in_chunk == 0) { + // this sample is the first sample in a chunk, so this is the start of a chunk + if (chunk_index >= chunk_offsets.ItemCount()) return AP4_ERROR_INTERNAL; + chunk_offsets[chunk_index] = mdat_position+mdat_size; + } + mdat_size += sample.GetSize(); + } + result = trak->SetChunkOffsets(chunk_offsets); } - + // write the moov atom movie->GetMoovAtom()->Write(stream); + + // create and write the media data (mdat) + // FIXME: this only supports 32-bit mdat size + stream.WriteUI32((AP4_UI32)mdat_size); + stream.WriteUI32(AP4_ATOM_TYPE_MDAT); + + // write all tracks and restore the chunk offsets to their backed-up values + for (AP4_List<AP4_Track>::Item* track_item = movie->GetTracks().FirstItem(); + track_item; + track_item = track_item->GetNext(), ++t) { + AP4_Track* track = track_item->GetData(); + AP4_TrakAtom* trak = track->GetTrakAtom(); + + // restore the backed-up chunk offsets + result = trak->SetChunkOffsets(*trak_chunk_offsets_backup[t]); - // create an mdat - stream.WriteUI32(0); - stream.Write("mdat", 4); - AP4_Track* track = movie->GetTracks().FirstItem()->GetData(); - AP4_Cardinal sample_count = track->GetSampleCount(); - for (AP4_Ordinal i=0; i<sample_count; i++) { - AP4_Sample sample; - AP4_DataBuffer data; - track->ReadSample(i, sample, data); - stream.Write(data.GetData(), data.GetDataSize()); + // write all the track's samples + AP4_Cardinal sample_count = track->GetSampleCount(); + AP4_Sample sample; + AP4_DataBuffer sample_data; + for (AP4_Ordinal i=0; i<sample_count; i++) { + track->ReadSample(i, sample, sample_data); + stream.Write(sample_data.GetData(), sample_data.GetDataSize()); + } } - // TODO: update the mdat size - - return AP4_SUCCESS; +end: + for (unsigned int i=0; i<trak_chunk_offsets_backup.ItemCount(); i++) { + delete trak_chunk_offsets_backup[i]; + } + + return result; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileWriter.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileWriter.h index b8f5b3df8..4c5c75391 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileWriter.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FileWriter.h @@ -2,7 +2,7 @@ | | AP4 - File Writer | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,29 +30,34 @@ #define _AP4_FILE_WRITER_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4Atom.h" -#include "Ap4Track.h" -#include "Ap4List.h" -#include "Ap4ByteStream.h" -#include "Ap4File.h" +#include "Ap4Types.h" /*---------------------------------------------------------------------- -| AP4_FileWriter +| class references +---------------------------------------------------------------------*/ -class AP4_FileWriter { - public: - // constructors and destructor - AP4_FileWriter(AP4_File& file); - virtual ~AP4_FileWriter(); - - // methods - AP4_Result Write(AP4_ByteStream& stream); +class AP4_ByteStream; +class AP4_File; - private: - AP4_File& m_File; +/*---------------------------------------------------------------------- +| AP4_FileWriter ++---------------------------------------------------------------------*/ +class AP4_FileWriter { +public: + // types + typedef enum { + INTERLEAVING_SEQUENTIAL + } Interleaving; + + // class methods + static AP4_Result Write(AP4_File& file, + AP4_ByteStream& stream, + Interleaving interleaving = INTERLEAVING_SEQUENTIAL); + +private: + // don't instantiate this class + AP4_FileWriter() {} }; #endif // _AP4_FILE_WRITER_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FrmaAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FrmaAtom.cpp index 41a8a92f0..cfaef69b3 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FrmaAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FrmaAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - frma Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,33 +27,32 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4FrmaAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_FrmaAtom::AP4_FrmaAtom +| AP4_FrmaAtom::AP4_FrmaAtom +---------------------------------------------------------------------*/ AP4_FrmaAtom::AP4_FrmaAtom(AP4_UI32 original_format) : - AP4_Atom(AP4_ATOM_TYPE_FRMA, AP4_ATOM_HEADER_SIZE+4, false), + AP4_Atom(AP4_ATOM_TYPE_FRMA, AP4_ATOM_HEADER_SIZE+4), m_OriginalFormat(original_format) { } /*---------------------------------------------------------------------- -| AP4_FrmaAtom::AP4_FrmaAtom +| AP4_FrmaAtom::AP4_FrmaAtom +---------------------------------------------------------------------*/ -AP4_FrmaAtom::AP4_FrmaAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_FRMA, size, false, stream) +AP4_FrmaAtom::AP4_FrmaAtom(AP4_UI32 size, AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_FRMA, size) { stream.ReadUI32(m_OriginalFormat); } /*---------------------------------------------------------------------- -| AP4_FrmaAtom::WriteFields +| AP4_FrmaAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_FrmaAtom::WriteFields(AP4_ByteStream& stream) @@ -63,7 +62,7 @@ AP4_FrmaAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_FrmaAtom::InspectFields +| AP4_FrmaAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_FrmaAtom::InspectFields(AP4_AtomInspector& inspector) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FrmaAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FrmaAtom.h index 8e15d7654..c6ea77a08 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FrmaAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FrmaAtom.h @@ -2,7 +2,7 @@ | | AP4 - frma Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,21 +30,28 @@ #define _AP4_FRMA_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4List.h" +#include "Ap4Types.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_FrmaAtom +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| AP4_FrmaAtom +---------------------------------------------------------------------*/ class AP4_FrmaAtom : public AP4_Atom { - public: +public: + // class methods + static AP4_FrmaAtom* Create(AP4_Size size, AP4_ByteStream& stream) { + return new AP4_FrmaAtom(size, stream); + } + // constructors - AP4_FrmaAtom(AP4_Size size, AP4_ByteStream& stream); AP4_FrmaAtom(AP4_UI32 original_format); // methods @@ -52,7 +59,10 @@ class AP4_FrmaAtom : public AP4_Atom virtual AP4_Result WriteFields(AP4_ByteStream& stream); AP4_UI32 GetOriginalFormat() { return m_OriginalFormat; } - private: +private: + // methods + AP4_FrmaAtom(AP4_UI32 size, AP4_ByteStream& stream); + // members AP4_UI32 m_OriginalFormat; }; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FtypAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FtypAtom.cpp index a08637dbf..8bd20f0cc 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FtypAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FtypAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - ftyp Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,18 +27,22 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4FtypAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_FtypAtom::AP4_FtypAtom +| dynamic cast support +---------------------------------------------------------------------*/ -AP4_FtypAtom::AP4_FtypAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_FTYP, size, false, stream) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_FtypAtom) + +/*---------------------------------------------------------------------- +| AP4_FtypAtom::AP4_FtypAtom ++---------------------------------------------------------------------*/ +AP4_FtypAtom::AP4_FtypAtom(AP4_UI32 size, AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_FTYP, size) { stream.ReadUI32(m_MajorBrand); stream.ReadUI32(m_MinorVersion); @@ -52,7 +56,34 @@ AP4_FtypAtom::AP4_FtypAtom(AP4_Size size, AP4_ByteStream& stream) : } /*---------------------------------------------------------------------- -| AP4_FtypAtom::WriteFields +| AP4_FtypAtom::AP4_FtypAtom ++---------------------------------------------------------------------*/ +AP4_FtypAtom::AP4_FtypAtom(AP4_UI32 major_brand, + AP4_UI32 minor_version, + AP4_UI32* compatible_brands, + AP4_Cardinal compatible_brand_count) : + AP4_Atom(AP4_ATOM_TYPE_FTYP, AP4_ATOM_HEADER_SIZE+8+4*compatible_brand_count), + m_MajorBrand(major_brand), + m_MinorVersion(minor_version), + m_CompatibleBrands(compatible_brands, compatible_brand_count) +{ +} + +/*---------------------------------------------------------------------- +| AP4_FtypAtom::HasCompatibleBrand ++---------------------------------------------------------------------*/ +bool +AP4_FtypAtom::HasCompatibleBrand(AP4_UI32 brand) +{ + for (unsigned int i=0; i<m_CompatibleBrands.ItemCount(); i++) { + if (m_CompatibleBrands[i] == brand) return true; + } + + return false; +} + +/*---------------------------------------------------------------------- +| AP4_FtypAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_FtypAtom::WriteFields(AP4_ByteStream& stream) @@ -78,7 +109,7 @@ AP4_FtypAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_FtypAtom::InspectFields +| AP4_FtypAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_FtypAtom::InspectFields(AP4_AtomInspector& inspector) @@ -86,7 +117,7 @@ AP4_FtypAtom::InspectFields(AP4_AtomInspector& inspector) char name[5]; AP4_FormatFourChars(name, m_MajorBrand); inspector.AddField("major_brand", name); - inspector.AddField("minor_version", m_MinorVersion); + inspector.AddField("minor_version", m_MinorVersion, AP4_AtomInspector::HINT_HEX); // compatible brands for (unsigned int i=0; i<m_CompatibleBrands.ItemCount(); i++) { diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FtypAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FtypAtom.h index 0eec5905b..fe6e2c0f4 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FtypAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4FtypAtom.h @@ -2,7 +2,7 @@ | | AP4 - ftyp Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,26 +30,55 @@ #define _AP4_FTYP_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4List.h" +#include "Ap4Types.h" #include "Ap4Atom.h" #include "Ap4Array.h" /*---------------------------------------------------------------------- -| AP4_FtypAtom +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_FTYP_BRAND_ISOM = AP4_ATOM_TYPE('i','s','o','m'); + +/*---------------------------------------------------------------------- +| AP4_FtypAtom +---------------------------------------------------------------------*/ class AP4_FtypAtom : public AP4_Atom { - public: +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_FtypAtom, AP4_Atom) + + // class methods + static AP4_FtypAtom* Create(AP4_Size size, AP4_ByteStream& stream) { + return new AP4_FtypAtom(size, stream); + } + // methods - AP4_FtypAtom(AP4_Size size, AP4_ByteStream& stream); + AP4_FtypAtom(AP4_UI32 major_brand, + AP4_UI32 minor_version, + AP4_UI32* compatible_brands = NULL, + AP4_Cardinal compatible_brand_count = 0); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // accessors + AP4_UI32 GetMajorBrand() { return m_MajorBrand; } + AP4_UI32 GetMinorVersion() { return m_MinorVersion; } + AP4_Array<AP4_UI32>& GetCompatibleBrands() { + return m_CompatibleBrands; + } + bool HasCompatibleBrand(AP4_UI32 brand); + +private: + // methods + AP4_FtypAtom(AP4_UI32 size, AP4_ByteStream& stream); - private: // members AP4_UI32 m_MajorBrand; AP4_UI32 m_MinorVersion; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4GrpiAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4GrpiAtom.cpp new file mode 100644 index 000000000..f75764a14 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4GrpiAtom.cpp @@ -0,0 +1,137 @@ +/***************************************************************** +| +| AP4 - ohdr 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 "Ap4Utils.h" +#include "Ap4GrpiAtom.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_GrpiAtom) + +/*---------------------------------------------------------------------- +| AP4_GrpiAtom::Create ++---------------------------------------------------------------------*/ +AP4_GrpiAtom* +AP4_GrpiAtom::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_GrpiAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_GrpiAtom::AP4_GrpiAtom ++---------------------------------------------------------------------*/ +AP4_GrpiAtom::AP4_GrpiAtom(AP4_UI08 key_encryption_method, + const char* group_id, + const AP4_UI08* group_key, + AP4_Size group_key_length) : + AP4_Atom(AP4_ATOM_TYPE_GRPI, AP4_FULL_ATOM_HEADER_SIZE, 0, 0), + m_KeyEncryptionMethod(key_encryption_method), + m_GroupId(group_id), + m_GroupKey(group_key, group_key_length) +{ + m_Size32 += 2+1+2+m_GroupId.GetLength()+group_key_length; +} + +/*---------------------------------------------------------------------- +| AP4_GrpiAtom::AP4_GrpiAtom ++---------------------------------------------------------------------*/ +AP4_GrpiAtom::AP4_GrpiAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_GRPI, size, false, version, flags) +{ + // group id length + AP4_UI16 group_id_length = 0; + stream.ReadUI16(group_id_length); + + // encryption method + stream.ReadUI08(m_KeyEncryptionMethod); + + // group key length + AP4_UI16 group_key_length = 0; + stream.ReadUI16(group_key_length); + + // group id + char* group_id = new char[group_id_length]; + stream.Read(group_id, group_id_length); + m_GroupId.Assign(group_id, group_id_length); + delete[] group_id; + + // group key + m_GroupKey.SetDataSize(group_key_length); + stream.Read(m_GroupKey.UseData(), group_key_length); +} + +/*---------------------------------------------------------------------- +| AP4_GrpiAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_GrpiAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_CHECK(stream.WriteUI16((AP4_UI16)m_GroupId.GetLength())); + AP4_CHECK(stream.WriteUI08(m_KeyEncryptionMethod)); + AP4_CHECK(stream.WriteUI16((AP4_UI16)m_GroupKey.GetDataSize())); + AP4_CHECK(stream.Write(m_GroupId.GetChars(), m_GroupId.GetLength())); + AP4_CHECK(stream.Write(m_GroupKey.GetData(), m_GroupKey.GetDataSize())); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_GrpiAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_GrpiAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("key encryption method", m_KeyEncryptionMethod); + inspector.AddField("group id", m_GroupId.GetChars()); + inspector.AddField("group key", m_GroupKey.GetData(), + m_GroupKey.GetDataSize()); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_GrpiAtom::Clone ++---------------------------------------------------------------------*/ +AP4_Atom* +AP4_GrpiAtom::Clone() +{ + return new AP4_GrpiAtom(m_KeyEncryptionMethod, + m_GroupId.GetChars(), + m_GroupKey.GetData(), + m_GroupKey.GetDataSize()); +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4GrpiAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4GrpiAtom.h new file mode 100644 index 000000000..80aeae6c2 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4GrpiAtom.h @@ -0,0 +1,82 @@ +/***************************************************************** +| +| AP4 - grpi Atom +| +| 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_GRPI_ATOM_H_ +#define _AP4_GRPI_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" +#include "Ap4String.h" +#include "Ap4DataBuffer.h" + +/*---------------------------------------------------------------------- +| AP4_GrpiAtom ++---------------------------------------------------------------------*/ +class AP4_GrpiAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_GrpiAtom, AP4_Atom) + + // class methods + static AP4_GrpiAtom* Create(AP4_Size size, + AP4_ByteStream& stream); + + // constructor + AP4_GrpiAtom(AP4_UI08 key_encryption_method, + const char* group_id, + const AP4_UI08* group_key, + AP4_Size group_key_length); + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Atom* Clone(); + + // accessors + AP4_UI08 GetKeyEncryptionMethod() const { return m_KeyEncryptionMethod; } + void SetKeyEncryptionMethod(AP4_UI08 encryption_method) { m_KeyEncryptionMethod = encryption_method; } + const AP4_String& GetGroupId() const { return m_GroupId; } + const AP4_DataBuffer& GetGroupKey() const { return m_GroupKey; } + +private: + // methods + AP4_GrpiAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI08 m_KeyEncryptionMethod; + AP4_String m_GroupId; + AP4_DataBuffer m_GroupKey; +}; + +#endif // _AP4_GRPI_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HdlrAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HdlrAtom.cpp index e6a14ffb8..9a25e3ed3 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HdlrAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HdlrAtom.cpp @@ -1,110 +1,146 @@ -/*****************************************************************
-|
-| AP4 - hdlr Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4HdlrAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_HdlrAtom::AP4_HdlrAtom
-+---------------------------------------------------------------------*/
-AP4_HdlrAtom::AP4_HdlrAtom(AP4_Atom::Type hdlr_type, const char* hdlr_name) :
- AP4_Atom(AP4_ATOM_TYPE_HDLR, true),
- m_HandlerType(hdlr_type),
- m_HandlerName(hdlr_name)
-{
- m_Size += 20+m_HandlerName.length()+1;
-}
-
-/*----------------------------------------------------------------------
-| AP4_HdlrAtom::AP4_HdlrAtom
-+---------------------------------------------------------------------*/
-AP4_HdlrAtom::AP4_HdlrAtom(AP4_Size size, AP4_ByteStream& stream) :
- AP4_Atom(AP4_ATOM_TYPE_HDLR, size, true, stream)
-{
- unsigned char reserved[12];
- stream.Read(reserved, 4, NULL);
- stream.ReadUI32(m_HandlerType);
- stream.Read(reserved, 12, NULL);
-
- // read the name unless it is empty
- int name_size = size-(AP4_FULL_ATOM_HEADER_SIZE+20);
- if (name_size > 0) {
- char* name = DNew char[name_size+1];
- stream.Read(name, name_size);
- name[name_size] = '\0'; // force a null termination
- m_HandlerName = name;
- delete[] name;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_HdlrAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_HdlrAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // write the data
- unsigned char reserved[12];
- memset(reserved, 0, sizeof(reserved));
- result = stream.Write(reserved, 4);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_HandlerType);
- if (AP4_FAILED(result)) return result;
- result = stream.Write(reserved, 12);
- if (AP4_FAILED(result)) return result;
- result = stream.Write(m_HandlerName.c_str(),
- m_HandlerName.length()+1);
- if (AP4_FAILED(result)) return result;
-
- // pad with zeros if necessary
- AP4_Size padding = m_Size-(AP4_FULL_ATOM_HEADER_SIZE+20+m_HandlerName.length()+1);
- while (padding--) stream.WriteUI08(0);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_HdlrAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_HdlrAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- char type[5];
- AP4_FormatFourChars(type, m_HandlerType);
- inspector.AddField("handler_type", type);
- inspector.AddField("handler_name", m_HandlerName.c_str());
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - hdlr 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 "Ap4HdlrAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_HdlrAtom) + +/*---------------------------------------------------------------------- +| AP4_HdlrAtom::Create ++---------------------------------------------------------------------*/ +AP4_HdlrAtom* +AP4_HdlrAtom::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_HdlrAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_HdlrAtom::AP4_HdlrAtom ++---------------------------------------------------------------------*/ +AP4_HdlrAtom::AP4_HdlrAtom(AP4_Atom::Type hdlr_type, const char* hdlr_name) : + AP4_Atom(AP4_ATOM_TYPE_HDLR, AP4_FULL_ATOM_HEADER_SIZE, 0, 0), + m_HandlerType(hdlr_type), + m_HandlerName(hdlr_name) +{ + m_Size32 += 20+m_HandlerName.GetLength()+1; + m_Reserved[0] = m_Reserved[1] = m_Reserved[2] = 0; +} + +/*---------------------------------------------------------------------- +| AP4_HdlrAtom::AP4_HdlrAtom ++---------------------------------------------------------------------*/ +AP4_HdlrAtom::AP4_HdlrAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_HDLR, size, version, flags) +{ + AP4_UI32 predefined; + stream.ReadUI32(predefined); + stream.ReadUI32(m_HandlerType); + stream.ReadUI32(m_Reserved[0]); + stream.ReadUI32(m_Reserved[1]); + stream.ReadUI32(m_Reserved[2]); + + // read the name unless it is empty + int name_size = size-(AP4_FULL_ATOM_HEADER_SIZE+20); + if (name_size == 0) return; + char* name = new char[name_size+1]; + stream.Read(name, name_size); + name[name_size] = '\0'; // force a null termination + // handle a special case: the Quicktime files have a pascal + // string here, but ISO MP4 files have a C string. + // we try to detect a pascal encoding and correct it. + if (name[0] == name_size-1) { + m_HandlerName = name+1; + } else { + m_HandlerName = name; + } + delete[] name; +} + +/*---------------------------------------------------------------------- +| AP4_HdlrAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_HdlrAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // write the data + result = stream.WriteUI32(0); // predefined + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_HandlerType); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_Reserved[0]); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_Reserved[1]); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_Reserved[2]); + if (AP4_FAILED(result)) return result; + AP4_UI08 name_size = (AP4_UI08)m_HandlerName.GetLength(); + if (AP4_FULL_ATOM_HEADER_SIZE+20+name_size > m_Size32) { + name_size = m_Size32-AP4_FULL_ATOM_HEADER_SIZE+20; + } + if (name_size) { + result = stream.Write(m_HandlerName.GetChars(), name_size); + if (AP4_FAILED(result)) return result; + } + + // pad with zeros if necessary + AP4_Size padding = m_Size32-(AP4_FULL_ATOM_HEADER_SIZE+20+name_size); + while (padding--) stream.WriteUI08(0); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_HdlrAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_HdlrAtom::InspectFields(AP4_AtomInspector& inspector) +{ + char type[5]; + AP4_FormatFourChars(type, m_HandlerType); + inspector.AddField("handler_type", type); + inspector.AddField("handler_name", m_HandlerName.GetChars()); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HdlrAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HdlrAtom.h index 63b9d1507..c5b1bf135 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HdlrAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HdlrAtom.h @@ -1,71 +1,91 @@ -/*****************************************************************
-|
-| AP4 - hdlr Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_HDLR_ATOM_H_
-#define _AP4_HDLR_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4List.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| constants
-+---------------------------------------------------------------------*/
-const AP4_UI32 AP4_HANDLER_TYPE_SOUN = AP4_ATOM_TYPE('s','o','u','n');
-const AP4_UI32 AP4_HANDLER_TYPE_VIDE = AP4_ATOM_TYPE('v','i','d','e');
-const AP4_UI32 AP4_HANDLER_TYPE_TEXT = AP4_ATOM_TYPE('t','e','x','t');
-const AP4_UI32 AP4_HANDLER_TYPE_TX3G = AP4_ATOM_TYPE('t','x','3','g');
-const AP4_UI32 AP4_HANDLER_TYPE_SUBP = AP4_ATOM_TYPE('s','u','b','p');
-const AP4_UI32 AP4_HANDLER_TYPE_HINT = AP4_ATOM_TYPE('h','i','n','t');
-
-/*----------------------------------------------------------------------
-| AP4_HdlrAtom
-+---------------------------------------------------------------------*/
-class AP4_HdlrAtom : public AP4_Atom
-{
-public:
- // methods
- AP4_HdlrAtom(AP4_UI32 hdlr_type, const char* hdlr_name);
- AP4_HdlrAtom(AP4_Size size, AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
-
- AP4_UI32 GetHandlerType() { return m_HandlerType; }
- AP4_String GetHandlerName() { return m_HandlerName; }
-
-private:
- // members
- AP4_UI32 m_HandlerType;
- AP4_String m_HandlerName;
-};
-
-#endif // _AP4_HDLR_ATOM_H_
+/***************************************************************** +| +| AP4 - hdlr 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_HDLR_ATOM_H_ +#define _AP4_HDLR_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" +#include "Ap4String.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_HANDLER_TYPE_SOUN = AP4_ATOM_TYPE('s','o','u','n'); +const AP4_UI32 AP4_HANDLER_TYPE_VIDE = AP4_ATOM_TYPE('v','i','d','e'); +const AP4_UI32 AP4_HANDLER_TYPE_HINT = AP4_ATOM_TYPE('h','i','n','t'); +const AP4_UI32 AP4_HANDLER_TYPE_MDIR = AP4_ATOM_TYPE('m','d','i','r'); +const AP4_UI32 AP4_HANDLER_TYPE_TEXT = AP4_ATOM_TYPE('t','e','x','t'); +const AP4_UI32 AP4_HANDLER_TYPE_TX3G = AP4_ATOM_TYPE('t','x','3','g'); +const AP4_UI32 AP4_HANDLER_TYPE_JPEG = AP4_ATOM_TYPE('j','p','e','g'); +const AP4_UI32 AP4_HANDLER_TYPE_ODSM = AP4_ATOM_TYPE('o','d','s','m'); +const AP4_UI32 AP4_HANDLER_TYPE_SDSM = AP4_ATOM_TYPE('s','d','s','m'); +// ==> Start patch MPC +const AP4_UI32 AP4_HANDLER_TYPE_SUBP = AP4_ATOM_TYPE('s','u','b','p'); +// <== End patch MPC + +/*---------------------------------------------------------------------- +| AP4_HdlrAtom ++---------------------------------------------------------------------*/ +class AP4_HdlrAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_HdlrAtom, AP4_Atom) + + // class methods + static AP4_HdlrAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_HdlrAtom(AP4_UI32 hdlr_type, const char* hdlr_name); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + AP4_UI32 GetHandlerType() { return m_HandlerType; } + AP4_String GetHandlerName() { return m_HandlerName; } + +private: + // methods + AP4_HdlrAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI32 m_HandlerType; + AP4_UI32 m_Reserved[3]; + AP4_String m_HandlerName; +}; + +#endif // _AP4_HDLR_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HintTrackReader.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HintTrackReader.cpp index b3ae303bb..3e35131cb 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HintTrackReader.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HintTrackReader.cpp @@ -2,7 +2,7 @@ | | AP4 - Hint Track Reader | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,7 +27,7 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include <stdlib.h> #include <time.h> @@ -43,11 +43,11 @@ #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_HintTrackReader::AP4_HintTrackReader +| AP4_HintTrackReader::AP4_HintTrackReader +---------------------------------------------------------------------*/ AP4_HintTrackReader::AP4_HintTrackReader(AP4_Track& hint_track, - AP4_Movie& movie, - AP4_UI32 ssrc /* = 0 */) : + AP4_Movie& movie, + AP4_UI32 ssrc) : m_HintTrack(hint_track), m_MediaTrack(NULL), m_MediaTimeScale(0), @@ -59,15 +59,11 @@ AP4_HintTrackReader::AP4_HintTrackReader(AP4_Track& hint_track, m_RtpTimeStampStart(0), m_RtpTimeScale(0) { - // check the type - if (m_HintTrack.GetType() != AP4_Track::TYPE_HINT) - throw AP4_Exception(AP4_ERROR_INVALID_TRACK_TYPE); - // get the media track AP4_TrakAtom* hint_trak_atom = hint_track.GetTrakAtom(); AP4_Atom* atom = hint_trak_atom->FindChild("tref/hint"); if (atom != NULL) { - AP4_UI32 media_track_id = ((AP4_TrefTypeAtom*) atom)->m_TrackIds[0]; + AP4_UI32 media_track_id = ((AP4_TrefTypeAtom*) atom)->GetTrackIds()[0]; m_MediaTrack = movie.GetTrack(media_track_id); // get the media time scale @@ -75,7 +71,7 @@ AP4_HintTrackReader::AP4_HintTrackReader(AP4_Track& hint_track, } // initiate random generator - srand(time(NULL)); + srand((int)time(NULL)); // rtp sequence start init TODO!! m_RtpSequenceStart = rand(); @@ -100,7 +96,30 @@ AP4_HintTrackReader::AP4_HintTrackReader(AP4_Track& hint_track, } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::~AP4_HintTrackReader +| AP4_HintTrackReader::Create ++---------------------------------------------------------------------*/ +AP4_Result +AP4_HintTrackReader::Create(AP4_Track& hint_track, + AP4_Movie& movie, + AP4_UI32 ssrc, + AP4_HintTrackReader*& reader) +{ + // default value + reader = NULL; + + // check the type + if (hint_track.GetType() != AP4_Track::TYPE_HINT) { + return AP4_ERROR_INVALID_TRACK_TYPE; + } + + // create a new object + reader = new AP4_HintTrackReader(hint_track, movie, ssrc); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_HintTrackReader::~AP4_HintTrackReader +---------------------------------------------------------------------*/ AP4_HintTrackReader::~AP4_HintTrackReader() { @@ -108,7 +127,7 @@ AP4_HintTrackReader::~AP4_HintTrackReader() } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::GetRtpSample +| AP4_HintTrackReader::GetRtpSample +---------------------------------------------------------------------*/ AP4_Result AP4_HintTrackReader::GetRtpSample(AP4_Ordinal index) @@ -121,7 +140,7 @@ AP4_HintTrackReader::GetRtpSample(AP4_Ordinal index) delete m_RtpSampleData; AP4_ByteStream& rtp_data_stream = *m_CurrentHintSample.GetDataStream(); rtp_data_stream.Seek(m_CurrentHintSample.GetOffset()); - m_RtpSampleData = DNew AP4_RtpSampleData(rtp_data_stream, + m_RtpSampleData = new AP4_RtpSampleData(rtp_data_stream, m_CurrentHintSample.GetSize()); // reinit the packet index @@ -134,18 +153,18 @@ AP4_HintTrackReader::GetRtpSample(AP4_Ordinal index) } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::GetCurrentTimeStampMs +| AP4_HintTrackReader::GetCurrentTimeStampMs +---------------------------------------------------------------------*/ -AP4_TimeStamp +AP4_UI32 AP4_HintTrackReader::GetCurrentTimeStampMs() { - return AP4_ConvertTime(m_CurrentHintSample.GetCts(), - m_HintTrack.GetMediaTimeScale(), - 1000); + return (AP4_UI32)AP4_ConvertTime(m_CurrentHintSample.GetCts(), + m_HintTrack.GetMediaTimeScale(), + 1000); } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::Rewind +| AP4_HintTrackReader::Rewind +---------------------------------------------------------------------*/ AP4_Result AP4_HintTrackReader::Rewind() @@ -155,7 +174,7 @@ AP4_HintTrackReader::Rewind() } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::GetSdpText +| AP4_HintTrackReader::GetSdpText +---------------------------------------------------------------------*/ AP4_Result AP4_HintTrackReader::GetSdpText(AP4_String& sdp_text) @@ -169,15 +188,15 @@ AP4_HintTrackReader::GetSdpText(AP4_String& sdp_text) } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::SeekToTimeStampMs +| AP4_HintTrackReader::SeekToTimeStampMs +---------------------------------------------------------------------*/ AP4_Result -AP4_HintTrackReader::SeekToTimeStampMs(AP4_TimeStamp desired_ts, - AP4_TimeStamp& actual_ts) +AP4_HintTrackReader::SeekToTimeStampMs(AP4_UI32 desired_ts_ms, + AP4_UI32& actual_ts_ms) { // get the sample index AP4_Cardinal index; - AP4_Result result = m_HintTrack.GetSampleIndexForTimeStampMs(desired_ts, index); + AP4_Result result = m_HintTrack.GetSampleIndexForTimeStampMs(desired_ts_ms, index); if (AP4_FAILED(result)) return result; // get the current sample based on the index and renew the sample data @@ -185,16 +204,16 @@ AP4_HintTrackReader::SeekToTimeStampMs(AP4_TimeStamp desired_ts, if (AP4_FAILED(result)) return result; // set the actual ts - actual_ts = GetCurrentTimeStampMs(); + actual_ts_ms = GetCurrentTimeStampMs(); return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::GetNextPacket +| AP4_HintTrackReader::GetNextPacket +---------------------------------------------------------------------*/ AP4_Result AP4_HintTrackReader::GetNextPacket(AP4_DataBuffer& packet_data, - AP4_TimeStamp& ts_ms) + AP4_UI32& ts_ms) { AP4_Result result = AP4_SUCCESS; @@ -222,10 +241,10 @@ AP4_HintTrackReader::GetNextPacket(AP4_DataBuffer& packet_data, } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::BuildRtpPacket +| AP4_HintTrackReader::BuildRtpPacket +---------------------------------------------------------------------*/ AP4_Result -AP4_HintTrackReader::BuildRtpPacket(AP4_RtpPacket* packet, +AP4_HintTrackReader::BuildRtpPacket(AP4_RtpPacket* packet, AP4_DataBuffer& packet_data) { // set the data size @@ -233,14 +252,13 @@ AP4_HintTrackReader::BuildRtpPacket(AP4_RtpPacket* packet, if (AP4_FAILED(result)) return result; // now write - AP4_ByteStream* stream = - DNew AP4_MemoryByteStream(packet_data.UseData(), packet_data.GetDataSize()); + AP4_ByteStream* stream = new AP4_MemoryByteStream(packet_data); // header + ssrc stream->WriteUI08(0x80 | (packet->GetPBit() << 5) | (packet->GetXBit() << 4)); stream->WriteUI08((packet->GetMBit() << 7) | packet->GetPayloadType()); stream->WriteUI16(m_RtpSequenceStart + packet->GetSequenceSeed()); - stream->WriteUI32(m_RtpTimeStampStart + m_CurrentHintSample.GetCts() + packet->GetTimeStampOffset()); + stream->WriteUI32(m_RtpTimeStampStart + (AP4_UI32)m_CurrentHintSample.GetCts() + packet->GetTimeStampOffset()); stream->WriteUI32(m_Ssrc); AP4_List<AP4_RtpConstructor>::Item* constructors_it @@ -264,7 +282,7 @@ AP4_HintTrackReader::BuildRtpPacket(AP4_RtpPacket* packet, if (AP4_FAILED(result)) return result; break; case AP4_RTP_CONSTRUCTOR_TYPE_SAMPLE_DESC: - return AP4_ERROR_NOT_SUPPORTED_YET; + return AP4_ERROR_NOT_SUPPORTED; default: // unknown constructor type return AP4_FAILURE; @@ -281,22 +299,22 @@ AP4_HintTrackReader::BuildRtpPacket(AP4_RtpPacket* packet, } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::WriteImmediateRtpData +| AP4_HintTrackReader::WriteImmediateRtpData +---------------------------------------------------------------------*/ AP4_Result AP4_HintTrackReader::WriteImmediateRtpData(AP4_ImmediateRtpConstructor* constructor, - AP4_ByteStream* data_stream) + AP4_ByteStream* data_stream) { const AP4_DataBuffer& data_buffer = constructor->GetData(); return data_stream->Write(data_buffer.GetData(), data_buffer.GetDataSize()); } /*---------------------------------------------------------------------- -| AP4_HintTrackReader::WriteSampleRtpData +| AP4_HintTrackReader::WriteSampleRtpData +---------------------------------------------------------------------*/ AP4_Result AP4_HintTrackReader::WriteSampleRtpData(AP4_SampleRtpConstructor* constructor, - AP4_ByteStream* data_stream) + AP4_ByteStream* data_stream) { AP4_Track* referenced_track = NULL; if (constructor->GetTrackRefIndex() == 0xFF) { diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HintTrackReader.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HintTrackReader.h index a17aa13ed..71b2aebaa 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HintTrackReader.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HintTrackReader.h @@ -2,7 +2,7 @@ | | AP4 - Hint Track Reader | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,13 +30,13 @@ #define _AP4_HINT_TRACK_READER_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" +#include "Ap4Types.h" #include "Ap4Sample.h" /*---------------------------------------------------------------------- -| class declarations +| class declarations +---------------------------------------------------------------------*/ class AP4_DataBuffer; class AP4_Movie; @@ -45,38 +45,45 @@ class AP4_RtpSampleData; class AP4_RtpPacket; class AP4_ImmediateRtpConstructor; class AP4_SampleRtpConstructor; +class AP4_String; /*---------------------------------------------------------------------- -| AP4_HintTrackReader +| AP4_HintTrackReader +---------------------------------------------------------------------*/ class AP4_HintTrackReader { public: // constructor and destructor - AP4_HintTrackReader(AP4_Track& hint_track, - AP4_Movie& movie, - AP4_UI32 ssrc = 0); // if 0, random value is chosen + static AP4_Result Create(AP4_Track& hint_track, + AP4_Movie& movie, + AP4_UI32 ssrc, // if 0, a random value is chosen + AP4_HintTrackReader*& reader); ~AP4_HintTrackReader(); // methods AP4_Result GetNextPacket(AP4_DataBuffer& packet, - AP4_TimeStamp& ts_ms); - AP4_Result SeekToTimeStampMs(AP4_TimeStamp desired_ts, - AP4_TimeStamp& actual_ts); - AP4_TimeStamp GetCurrentTimeStampMs(); + AP4_UI32& ts_ms); + AP4_Result SeekToTimeStampMs(AP4_UI32 desired_ts_ms, + AP4_UI32& actual_ts_ms); + AP4_UI32 GetCurrentTimeStampMs(); AP4_Result Rewind(); AP4_Result GetSdpText(AP4_String& sdp); AP4_Track* GetMediaTrack() { return m_MediaTrack; } private: + // use the factory instead of the constructor + AP4_HintTrackReader(AP4_Track& hint_track, + AP4_Movie& movie, + AP4_UI32 ssrc); + // methods AP4_Result GetRtpSample(AP4_Ordinal index); - AP4_Result BuildRtpPacket(AP4_RtpPacket* packet, + AP4_Result BuildRtpPacket(AP4_RtpPacket* packet, AP4_DataBuffer& packet_data); AP4_Result WriteImmediateRtpData(AP4_ImmediateRtpConstructor* constructor, - AP4_ByteStream* data_stream); + AP4_ByteStream* data_stream); AP4_Result WriteSampleRtpData(AP4_SampleRtpConstructor* constructor, - AP4_ByteStream* data_stream); + AP4_ByteStream* data_stream); // members AP4_Track& m_HintTrack; @@ -88,7 +95,7 @@ private: AP4_Ordinal m_SampleIndex; AP4_Ordinal m_PacketIndex; AP4_UI16 m_RtpSequenceStart; - AP4_TimeStamp m_RtpTimeStampStart; + AP4_UI32 m_RtpTimeStampStart; AP4_UI32 m_RtpTimeScale; }; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HmhdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HmhdAtom.cpp index cecac40da..4864e260a 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HmhdAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HmhdAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - hmhd Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,18 +27,33 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4HmhdAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_HmhdAtom::AP4_HmhdAtom +| AP4_HmhdAtom::Create +---------------------------------------------------------------------*/ -AP4_HmhdAtom::AP4_HmhdAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_HMHD, size, true, stream) +AP4_HmhdAtom* +AP4_HmhdAtom::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_HmhdAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_HmhdAtom::AP4_HmhdAtom ++---------------------------------------------------------------------*/ +AP4_HmhdAtom::AP4_HmhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_HMHD, size, version, flags) { stream.ReadUI16(m_MaxPduSize); stream.ReadUI16(m_AvgPduSize); @@ -48,7 +63,7 @@ AP4_HmhdAtom::AP4_HmhdAtom(AP4_Size size, AP4_ByteStream& stream) : } /*---------------------------------------------------------------------- -| AP4_HmhdAtom::WriteFields +| AP4_HmhdAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_HmhdAtom::WriteFields(AP4_ByteStream& stream) @@ -79,7 +94,7 @@ AP4_HmhdAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_HmhdAtom::InspectFields +| AP4_HmhdAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_HmhdAtom::InspectFields(AP4_AtomInspector& inspector) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HmhdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HmhdAtom.h index a645dd3cc..c26417dc7 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HmhdAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4HmhdAtom.h @@ -2,7 +2,7 @@ | | AP4 - hmhd Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,24 +30,36 @@ #define _AP4_HMHD_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" +#include "Ap4Types.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_HmhdAtom +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| AP4_HmhdAtom +---------------------------------------------------------------------*/ class AP4_HmhdAtom : public AP4_Atom { public: + // class methods + static AP4_HmhdAtom* Create(AP4_Size size, AP4_ByteStream& stream); + // methods - AP4_HmhdAtom(AP4_Size size, AP4_ByteStream& stream); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); private: + // methods + AP4_HmhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + // members AP4_UI16 m_MaxPduSize; AP4_UI16 m_AvgPduSize; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IkmsAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IkmsAtom.cpp index cb5187127..8e2df2fb2 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IkmsAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IkmsAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - iKMS Atoms | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,30 +27,63 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4IkmsAtom.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_IkmsAtom::AP4_IkmsAtom +| dynamic cast support +---------------------------------------------------------------------*/ -AP4_IkmsAtom::AP4_IkmsAtom(const char* kms_uri) : - AP4_Atom(AP4_ATOM_TYPE_IKMS, AP4_FULL_ATOM_HEADER_SIZE, true), - m_KmsUri(kms_uri) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_IkmsAtom) + +/*---------------------------------------------------------------------- +| AP4_IkmsAtom::Create ++---------------------------------------------------------------------*/ +AP4_IkmsAtom* +AP4_IkmsAtom::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 > 1) return NULL; + return new AP4_IkmsAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_IkmsAtom::AP4_IkmsAtom ++---------------------------------------------------------------------*/ +AP4_IkmsAtom::AP4_IkmsAtom(const char* kms_uri, + AP4_UI32 kms_id, + AP4_UI32 kms_version) : + AP4_Atom(AP4_ATOM_TYPE_IKMS, AP4_FULL_ATOM_HEADER_SIZE, 0, 0), + m_KmsUri(kms_uri), + m_KmsId(kms_id), + m_KmsVersion(kms_version) { - m_Size += m_KmsUri.length()+1; + m_Size32 += m_KmsUri.GetLength()+1; } /*---------------------------------------------------------------------- -| AP4_IkmsAtom::AP4_IkmsAtom +| AP4_IkmsAtom::AP4_IkmsAtom +---------------------------------------------------------------------*/ -AP4_IkmsAtom::AP4_IkmsAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_IKMS, size, true, stream) +AP4_IkmsAtom::AP4_IkmsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_IKMS, size, version, flags) { AP4_Size string_size = size-AP4_FULL_ATOM_HEADER_SIZE; + if (m_Version == 1 && string_size >= 8) { + string_size -= 8; + stream.ReadUI32(m_KmsId); + stream.ReadUI32(m_KmsVersion); + } else { + m_KmsId = 0; + m_KmsVersion = 0; + } if (string_size) { - char* str = DNew char[string_size]; + char* str = new char[string_size]; stream.Read(str, string_size); str[string_size-1] = '\0'; // force null-termination m_KmsUri = str; @@ -59,38 +92,51 @@ AP4_IkmsAtom::AP4_IkmsAtom(AP4_Size size, AP4_ByteStream& stream) : } /*---------------------------------------------------------------------- -| AP4_IkmsAtom::Clone +| AP4_IkmsAtom::Clone +---------------------------------------------------------------------*/ AP4_Atom* AP4_IkmsAtom::Clone() { - return DNew AP4_IkmsAtom(m_KmsUri.c_str()); + return new AP4_IkmsAtom(m_KmsUri.GetChars(), m_KmsId, m_KmsVersion); } /*---------------------------------------------------------------------- -| AP4_IkmsAtom::WriteFields +| AP4_IkmsAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_IkmsAtom::WriteFields(AP4_ByteStream& stream) { + // handler version 1 + if (m_Version == 1) { + stream.WriteUI32(m_KmsId); + stream.WriteUI32(m_KmsVersion); + } + // kms uri - AP4_Result result = stream.Write(m_KmsUri.c_str(), m_KmsUri.length()+1); + AP4_Result result = stream.Write(m_KmsUri.GetChars(), m_KmsUri.GetLength()+1); if (AP4_FAILED(result)) return result; // pad with zeros if necessary - AP4_Size padding = m_Size-(AP4_FULL_ATOM_HEADER_SIZE+m_KmsUri.length()+1); + AP4_Size padding = m_Size32-(AP4_FULL_ATOM_HEADER_SIZE+m_KmsUri.GetLength()+1); + if (m_Version == 1) padding-=8; while (padding--) stream.WriteUI08(0); return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_IkmsAtom::InspectFields +| AP4_IkmsAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_IkmsAtom::InspectFields(AP4_AtomInspector& inspector) { - inspector.AddField("kms_uri", m_KmsUri.c_str()); + if (m_Version == 1) { + char id[5]; + AP4_FormatFourChars(id, m_KmsId); + inspector.AddField("kms_id", id); + inspector.AddField("kms_version", m_KmsVersion); + } + inspector.AddField("kms_uri", m_KmsUri.GetChars()); return AP4_SUCCESS; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IkmsAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IkmsAtom.h index 7ff6efb40..7097b84bd 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IkmsAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IkmsAtom.h @@ -2,7 +2,7 @@ | | AP4 - iKMS Atom | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,31 +30,47 @@ #define _AP4_IKMS_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Types.h" -#include "Ap4ByteStream.h" #include "Ap4Atom.h" +#include "Ap4String.h" /*---------------------------------------------------------------------- -| AP4_IkmsAtom +| AP4_IkmsAtom +---------------------------------------------------------------------*/ class AP4_IkmsAtom : public AP4_Atom { public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_IkmsAtom, AP4_Atom) + + // class methods + static AP4_IkmsAtom* Create(AP4_Size size, AP4_ByteStream& stream); + // methods - AP4_IkmsAtom(const char* kms_uri); - AP4_IkmsAtom(AP4_Size size, AP4_ByteStream& stream); + AP4_IkmsAtom(const char* kms_uri, + AP4_UI32 kms_id = 0, + AP4_UI32 kms_version = 0); virtual AP4_Atom* Clone(); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); // accessors - const AP4_String& GetKmsUri() { return m_KmsUri; } + const AP4_String& GetKmsUri() { return m_KmsUri; } + AP4_UI32 GetKmsId() { return m_KmsId; } + AP4_UI32 GetKmsVersion() { return m_KmsVersion; } private: + // methods + AP4_IkmsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + // members AP4_String m_KmsUri; + AP4_UI32 m_KmsId; + AP4_UI32 m_KmsVersion; }; #endif // _AP4_IKMS_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Interfaces.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Interfaces.h index 8b505e93c..56502dab6 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Interfaces.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Interfaces.h @@ -2,7 +2,7 @@ | | AP4 - Common Interfaces | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,18 +30,19 @@ #define _AP4_INTERFACES_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Types.h" /*---------------------------------------------------------------------- -| macros +| macros +---------------------------------------------------------------------*/ #define AP4_RELEASE(o) do { if (o) (o)->Release(); (o) = NULL; } while (0) #define AP4_ADD_REFERENCE(o) do { if (o) (o)->AddReference(); } while (0) +#if !defined(AP4_CONFIG_NO_EXCEPTIONS) /*---------------------------------------------------------------------- -| AP4_Exception +| AP4_Exception +---------------------------------------------------------------------*/ class AP4_Exception { @@ -52,9 +53,10 @@ public: // members AP4_Result m_Error; }; +#endif /*---------------------------------------------------------------------- -| AP4_Referenceable +| AP4_Referenceable +---------------------------------------------------------------------*/ class AP4_Referenceable { diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IodsAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IodsAtom.cpp new file mode 100644 index 000000000..4baab3ce7 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IodsAtom.cpp @@ -0,0 +1,115 @@ +/***************************************************************** +| +| AP4 - iods Atom +| +| 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 "Ap4IodsAtom.h" +#include "Ap4DescriptorFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_IodsAtom) + +/*---------------------------------------------------------------------- +| AP4_IodsAtom::Create ++---------------------------------------------------------------------*/ +AP4_IodsAtom* +AP4_IodsAtom::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_IodsAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_IodsAtom::AP4_IodsAtom ++---------------------------------------------------------------------*/ +AP4_IodsAtom::AP4_IodsAtom(AP4_ObjectDescriptor* descriptor) : + AP4_Atom(AP4_ATOM_TYPE_IODS, AP4_FULL_ATOM_HEADER_SIZE, 0, 0), + m_ObjectDescriptor(descriptor) +{ + if (m_ObjectDescriptor) m_Size32 += m_ObjectDescriptor->GetSize(); +} + +/*---------------------------------------------------------------------- +| AP4_IodsAtom::AP4_IodsAtom ++---------------------------------------------------------------------*/ +AP4_IodsAtom::AP4_IodsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_IODS, size, version, flags) +{ + // read the descriptor + AP4_Descriptor* descriptor = NULL; + if (AP4_DescriptorFactory::CreateDescriptorFromStream(stream, descriptor) == AP4_SUCCESS) { + m_ObjectDescriptor = AP4_DYNAMIC_CAST(AP4_ObjectDescriptor, descriptor); + if (m_ObjectDescriptor == NULL) delete descriptor; + } else { + m_ObjectDescriptor = NULL; + } +} + +/*---------------------------------------------------------------------- +| AP4_IodsAtom::~AP4_IodsAtom ++---------------------------------------------------------------------*/ +AP4_IodsAtom::~AP4_IodsAtom() +{ + delete m_ObjectDescriptor; +} + +/*---------------------------------------------------------------------- +| AP4_IodsAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IodsAtom::WriteFields(AP4_ByteStream& stream) +{ + // write the es descriptor + if (m_ObjectDescriptor) return m_ObjectDescriptor->Write(stream); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_IodsAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IodsAtom::InspectFields(AP4_AtomInspector& inspector) +{ + // inspect descriptor + if (m_ObjectDescriptor) { + m_ObjectDescriptor->Inspect(inspector); + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UnknownDescriptor.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IodsAtom.h index 2b1c7414a..41c6c4cf0 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UnknownDescriptor.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IodsAtom.h @@ -1,8 +1,8 @@ /***************************************************************** | -| AP4 - Unknown Descriptors +| AP4 - iods Atom | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -24,35 +24,50 @@ | Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA | 02111-1307, USA. | -****************************************************************/ + ****************************************************************/ + +#ifndef _AP4_IODS_ATOM_H_ +#define _AP4_IODS_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4UnknownDescriptor.h" +#include "Ap4Types.h" +#include "Ap4Atom.h" +#include "Ap4ObjectDescriptor.h" /*---------------------------------------------------------------------- -| AP4_UnknownDescriptor::AP4_UnknownDescriptor +| class references +---------------------------------------------------------------------*/ -AP4_UnknownDescriptor::AP4_UnknownDescriptor(AP4_ByteStream& stream, - unsigned char tag, - AP4_Size header_size, - AP4_Size payload_size) : - AP4_Descriptor(tag, header_size, payload_size) -{ - m_Data.SetDataSize(payload_size); - stream.Read(m_Data.UseData(), payload_size); -} +class AP4_ByteStream; /*---------------------------------------------------------------------- -| AP4_UnknownDescriptor::WriteFields +| AP4_IodsAtom +---------------------------------------------------------------------*/ -AP4_Result -AP4_UnknownDescriptor::WriteFields(AP4_ByteStream& stream) +class AP4_IodsAtom : public AP4_Atom { - // write the payload - stream.Write(m_Data.GetData(), m_Data.GetDataSize()); +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_IodsAtom, AP4_Atom) + + // class methods + static AP4_IodsAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_IodsAtom(AP4_ObjectDescriptor* descriptor); // ownership of 'descriptor' is transfered + ~AP4_IodsAtom(); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + const AP4_ObjectDescriptor* GetObjectDescriptor() const { return m_ObjectDescriptor; } + +private: + // methods + AP4_IodsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_ObjectDescriptor* m_ObjectDescriptor; +}; - return AP4_SUCCESS; -} +#endif // _AP4_IODS_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Ipmp.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Ipmp.cpp new file mode 100644 index 000000000..c3e057ae1 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Ipmp.cpp @@ -0,0 +1,225 @@ +/***************************************************************** +| +| AP4 - IPMP +| +| 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 "Ap4Utils.h" +#include "Ap4ByteStream.h" +#include "Ap4Ipmp.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_IpmpDescriptor) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_IpmpDescriptorPointer) + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptorPointer::AP4_IpmpDescriptorPointer ++---------------------------------------------------------------------*/ +AP4_IpmpDescriptorPointer::AP4_IpmpDescriptorPointer(AP4_UI08 descriptor_id) : + AP4_Descriptor(AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR_POINTER, 2, 1), + m_DescriptorId(descriptor_id) +{ +} + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptorPointer::AP4_IpmpDescriptorPointer ++---------------------------------------------------------------------*/ +AP4_IpmpDescriptorPointer::AP4_IpmpDescriptorPointer(AP4_ByteStream& stream, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_Descriptor(AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR_POINTER, header_size, payload_size) +{ + stream.ReadUI08(m_DescriptorId); + if (m_DescriptorId == 0xFF && payload_size >= 5) { + stream.ReadUI16(m_DescriptorIdEx); + stream.ReadUI16(m_EsId); + } +} + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptorPointer::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IpmpDescriptorPointer::WriteFields(AP4_ByteStream& stream) +{ + stream.WriteUI08(m_DescriptorId); + if (m_DescriptorId == 0xFF) { + stream.WriteUI16(m_DescriptorIdEx); + stream.WriteUI16(m_EsId); + } + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptorPointer::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IpmpDescriptorPointer::Inspect(AP4_AtomInspector& inspector) +{ + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(),m_PayloadSize); + inspector.StartElement("[IPMP_DescriptorPointer]", info); + inspector.AddField("IPMP_DescriptorID", m_DescriptorId); + if (m_DescriptorId == 0xFF) { + inspector.AddField("IPMP_DescriptorIDEx", m_DescriptorIdEx); + inspector.AddField("IPMP_ES_ID", m_EsId); + } + + inspector.EndElement(); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptor::AP4_IpmpDescriptor ++---------------------------------------------------------------------*/ +AP4_IpmpDescriptor::AP4_IpmpDescriptor(AP4_UI08 descriptor_id, AP4_UI16 ipmps_type) : + AP4_Descriptor(AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR, 2, 3), + m_DescriptorId(descriptor_id), + m_IpmpsType(ipmps_type), + m_DescriptorIdEx(0), + m_ControlPointCode(0), + m_SequenceCode(0) +{ + AP4_SetMemory(m_ToolId, 0, sizeof(m_ToolId)); +} + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptor::AP4_IpmpDescriptor ++---------------------------------------------------------------------*/ +AP4_IpmpDescriptor::AP4_IpmpDescriptor(AP4_ByteStream& stream, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_Descriptor(AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR, header_size, payload_size), + m_DescriptorIdEx(0), + m_ControlPointCode(0), + m_SequenceCode(0) +{ + stream.ReadUI08(m_DescriptorId); + stream.ReadUI16(m_IpmpsType); + AP4_SetMemory(m_ToolId, 0, sizeof(m_ToolId)); + if (m_DescriptorId == 0xFF && m_IpmpsType == 0xFFFF) { + AP4_Size fields_size = 3+3; + stream.ReadUI16(m_DescriptorIdEx); + stream.Read(m_ToolId, 16); + stream.ReadUI08(m_ControlPointCode); + if (m_ControlPointCode > 0) { + stream.ReadUI08(m_SequenceCode); + ++fields_size; + } + if (fields_size < payload_size) { + m_Data.SetDataSize(payload_size-fields_size); + stream.Read(m_Data.UseData(), payload_size-fields_size); + } + } else if (m_IpmpsType == 0) { + if (payload_size > 3) { + char* buffer = new char[1+payload_size-3]; + buffer[payload_size-3] = '\0'; + stream.Read(buffer, payload_size-3); + m_Url.Assign(buffer, payload_size-3); + delete[] buffer; + } + } else { + if (payload_size > 3) { + m_Data.SetDataSize(payload_size-3); + stream.Read(m_Data.UseData(), payload_size-3); + } + } +} + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptor::SetData ++---------------------------------------------------------------------*/ +void +AP4_IpmpDescriptor::SetData(const unsigned char* data, AP4_Size data_size) +{ + m_Data.SetData(data, data_size); + m_PayloadSize += data_size; + m_HeaderSize = MinHeaderSize(m_PayloadSize); +} + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptor::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IpmpDescriptor::WriteFields(AP4_ByteStream& stream) +{ + stream.WriteUI08(m_DescriptorId); + stream.WriteUI16(m_IpmpsType); + if (m_DescriptorId == 0xFF && m_IpmpsType == 0xFFFF) { + stream.WriteUI16(m_DescriptorIdEx); + stream.Write(m_ToolId, 16); + stream.WriteUI08(m_ControlPointCode); + if (m_ControlPointCode > 0) { + stream.WriteUI08(m_SequenceCode); + } + if (m_Data.GetDataSize()) { + stream.Write(m_Data.GetData(), m_Data.GetDataSize()); + } + } else if (m_IpmpsType == 0) { + stream.Write(m_Url.GetChars(), m_Url.GetLength()+1); + } else { + stream.Write(m_Data.GetData(), m_Data.GetDataSize()); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptor::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IpmpDescriptor::Inspect(AP4_AtomInspector& inspector) +{ + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(),m_PayloadSize); + inspector.StartElement("[IPMP_Descriptor]", info); + inspector.AddField("IPMP_DescriptorID", m_DescriptorId); + inspector.AddField("IPMPS_Type", m_IpmpsType, AP4_AtomInspector::HINT_HEX); + if (m_DescriptorId == 0xFF && m_IpmpsType == 0xFFFF) { + inspector.AddField("IPMP_DescriptorIDEx", m_DescriptorIdEx); + inspector.AddField("IPMP_ToolID", (const unsigned char*)(&m_ToolId[0]), 16, AP4_AtomInspector::HINT_HEX); + inspector.AddField("controlPointCode", m_ControlPointCode); + if (m_ControlPointCode > 0) { + inspector.AddField("sequenceCode", m_SequenceCode); + } + } else if (m_IpmpsType == 0) { + inspector.AddField("URL", m_Url.GetChars()); + } else { + inspector.AddField("data size", m_Data.GetDataSize()); + } + + inspector.EndElement(); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Ipmp.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Ipmp.h new file mode 100644 index 000000000..52370af6d --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Ipmp.h @@ -0,0 +1,112 @@ +/***************************************************************** +| +| AP4 - IPMP +| +| 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_IPMP_H_ +#define _AP4_IPMP_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4String.h" +#include "Ap4Descriptor.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI08 AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR_POINTER = 0x0A; +const AP4_UI08 AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR = 0x0B; + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptorPointer ++---------------------------------------------------------------------*/ +class AP4_IpmpDescriptorPointer : public AP4_Descriptor +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_IpmpDescriptorPointer, AP4_Descriptor) + + // methods + AP4_IpmpDescriptorPointer(AP4_UI08 descriptor_id); + AP4_IpmpDescriptorPointer(AP4_ByteStream& stream, + AP4_Size header_size, + AP4_Size payload_size); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + + // accessors + AP4_UI08 GetDescriptorId() const { return m_DescriptorId; } + AP4_UI16 GetDescriptorIdEx() const { return m_DescriptorIdEx; } + AP4_UI16 GetEsId() const { return m_EsId; } + +private: + // members + AP4_UI08 m_DescriptorId; + AP4_UI16 m_DescriptorIdEx; + AP4_UI16 m_EsId; +}; + +/*---------------------------------------------------------------------- +| AP4_IpmpDescriptor ++---------------------------------------------------------------------*/ +class AP4_IpmpDescriptor : public AP4_Descriptor +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_IpmpDescriptor, AP4_Descriptor) + + // methods + AP4_IpmpDescriptor(AP4_UI08 descriptor_id, AP4_UI16 ipmps_type); + AP4_IpmpDescriptor(AP4_ByteStream& stream, + AP4_Size header_size, + AP4_Size payload_size); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + + // accessors + AP4_UI08 GetDescriptorId() const { return m_DescriptorId; } + AP4_UI16 GetIpmpsType() const { return m_IpmpsType; } + AP4_UI16 GetDescriptorIdEx() const { return m_DescriptorIdEx; } + const AP4_UI08* GetToolId() const { return m_ToolId; } + AP4_UI08 GetControlPointCode() const { return m_ControlPointCode; } + AP4_UI08 GetSequenceCode() const { return m_SequenceCode; } + const AP4_String& GetUrl() const { return m_Url; } + const AP4_DataBuffer& GetData() const { return m_Data; } + void SetData(const unsigned char* data, AP4_Size data_size); + +private: + // members + AP4_UI08 m_DescriptorId; + AP4_UI16 m_IpmpsType; + AP4_UI16 m_DescriptorIdEx; + AP4_UI08 m_ToolId[16]; + AP4_UI08 m_ControlPointCode; + AP4_UI08 m_SequenceCode; + AP4_String m_Url; + AP4_DataBuffer m_Data; +}; + +#endif // _AP4_IPMP_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IproAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IproAtom.cpp new file mode 100644 index 000000000..bf85194b1 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IproAtom.cpp @@ -0,0 +1,109 @@ +/***************************************************************** +| +| AP4 - ipro 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 "Ap4IproAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" +#include "Ap4SampleEntry.h" +#include "Ap4SampleTable.h" +#include "Ap4SampleDescription.h" + +/*---------------------------------------------------------------------- +| AP4_IproAtom::Create ++---------------------------------------------------------------------*/ +AP4_IproAtom* +AP4_IproAtom::Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) +{ + 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_IproAtom(size, version, flags, stream, atom_factory); +} + +/*---------------------------------------------------------------------- +| AP4_IproAtom::AP4_IproAtom ++---------------------------------------------------------------------*/ +AP4_IproAtom::AP4_IproAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_ContainerAtom(AP4_ATOM_TYPE_IPRO, size, false, version, flags) +{ + // read the number of entries + AP4_UI16 entry_count; + stream.ReadUI16(entry_count); + + // read all entries + AP4_LargeSize bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-2; + for (unsigned int i=0; i<entry_count; i++) { + AP4_Atom* atom; + if (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, + bytes_available, + atom))) { + atom->SetParent(this); + m_Children.Add(atom); + } + } +} + +/*---------------------------------------------------------------------- +| AP4_IproAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IproAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // entry count + result = stream.WriteUI16(m_Children.ItemCount()); + if (AP4_FAILED(result)) return result; + + // entries + return m_Children.Apply(AP4_AtomListWriter(stream)); +} + +/*---------------------------------------------------------------------- +| AP4_IproAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IproAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("entry-count", m_Children.ItemCount()); + + // inspect children + m_Children.Apply(AP4_AtomListInspector(inspector)); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CmvdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IproAtom.h index e61664724..a5c7d0d7f 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4CmvdAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IproAtom.h @@ -1,64 +1,64 @@ -/*****************************************************************
-|
-| AP4 - cmvd Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_CMVD_ATOM_H_
-#define _AP4_CMVD_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4Array.h"
-#include "Ap4Atom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4ContainerAtom.h"
-#include "Ap4DataBuffer.h"
-
-/*----------------------------------------------------------------------
-| AP4_CmvdAtom
-+---------------------------------------------------------------------*/
-class AP4_CmvdAtom : public AP4_ContainerAtom
-{
-public:
- // methods
- AP4_CmvdAtom(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
-
- virtual AP4_Result WriteFields(AP4_ByteStream& stream) { return AP4_FAILURE; }
-
- AP4_UI32 GetMovieResourceSize() const { return m_MovieResourceSize; }
- const AP4_DataBuffer& GetDataBuffer() { return m_Data; }
-
-private:
- AP4_UI32 m_MovieResourceSize;
- AP4_DataBuffer m_Data;
-};
-
-#endif // _AP4_CMVD_ATOM_H_
+/***************************************************************** +| +| AP4 - ipro 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_IPRO_ATOM_H_ +#define _AP4_IPRO_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Array.h" +#include "Ap4ContainerAtom.h" + +/*---------------------------------------------------------------------- +| AP4_IproAtom ++---------------------------------------------------------------------*/ +class AP4_IproAtom : public AP4_ContainerAtom +{ +public: + // class methods + static AP4_IproAtom* Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // methods + AP4_IproAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); +}; + +#endif // _AP4_IPRO_ATOM_H_ + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsfmAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsfmAtom.cpp index 3757df81d..8cd839eae 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsfmAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsfmAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - iSFM Atoms | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,18 +27,36 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Utils.h" #include "Ap4IsfmAtom.h" /*---------------------------------------------------------------------- -| AP4_IsfmAtom::AP4_IsfmAtom +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_IsfmAtom) + +/*---------------------------------------------------------------------- +| AP4_IsfmAtom::Create ++---------------------------------------------------------------------*/ +AP4_IsfmAtom* +AP4_IsfmAtom::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_IsfmAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_IsfmAtom::AP4_IsfmAtom +---------------------------------------------------------------------*/ AP4_IsfmAtom::AP4_IsfmAtom(bool selective_encryption, AP4_UI08 key_length_indicator, AP4_UI08 iv_length) : - AP4_Atom(AP4_ATOM_TYPE_ISFM, AP4_FULL_ATOM_HEADER_SIZE+3, true), + AP4_Atom(AP4_ATOM_TYPE_ISFM, AP4_FULL_ATOM_HEADER_SIZE+3, 0, 0), m_SelectiveEncryption(selective_encryption), m_KeyIndicatorLength(key_length_indicator), m_IvLength(iv_length) @@ -46,31 +64,34 @@ AP4_IsfmAtom::AP4_IsfmAtom(bool selective_encryption, } /*---------------------------------------------------------------------- -| AP4_IsfmAtom::AP4_IsfmAtom +| AP4_IsfmAtom::AP4_IsfmAtom +---------------------------------------------------------------------*/ -AP4_IsfmAtom::AP4_IsfmAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_ISFM, size, true, stream) +AP4_IsfmAtom::AP4_IsfmAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_ISFM, size, version, flags) { AP4_UI08 s; stream.ReadUI08(s); - m_SelectiveEncryption = ((s&1) != 0); + m_SelectiveEncryption = ((s&0x80) != 0); stream.ReadUI08(m_KeyIndicatorLength); stream.ReadUI08(m_IvLength); } /*---------------------------------------------------------------------- -| AP4_IsfmAtom::Clone +| AP4_IsfmAtom::Clone +---------------------------------------------------------------------*/ AP4_Atom* AP4_IsfmAtom::Clone() { - return DNew AP4_IsfmAtom(m_SelectiveEncryption, + return new AP4_IsfmAtom(m_SelectiveEncryption, m_KeyIndicatorLength, m_IvLength); } /*---------------------------------------------------------------------- -| AP4_IsfmAtom::WriteFields +| AP4_IsfmAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_IsfmAtom::WriteFields(AP4_ByteStream& stream) @@ -78,7 +99,7 @@ AP4_IsfmAtom::WriteFields(AP4_ByteStream& stream) AP4_Result result; // selective encryption - result = stream.WriteUI08(m_SelectiveEncryption ? 1 : 0); + result = stream.WriteUI08(m_SelectiveEncryption ? 0x80 : 0); if (AP4_FAILED(result)) return result; // key indicator length @@ -93,7 +114,7 @@ AP4_IsfmAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_IsfmAtom::InspectFields +| AP4_IsfmAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_IsfmAtom::InspectFields(AP4_AtomInspector& inspector) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsfmAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsfmAtom.h index fd07277f2..be6ab8382 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsfmAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsfmAtom.h @@ -2,7 +2,7 @@ | | AP4 - iSFM Atom | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,23 +30,26 @@ #define _AP4_ISFM_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Types.h" -#include "Ap4ByteStream.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_IsfmAtom +| AP4_IsfmAtom +---------------------------------------------------------------------*/ class AP4_IsfmAtom : public AP4_Atom { public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_IsfmAtom, AP4_Atom) + + // class methods + static AP4_IsfmAtom* Create(AP4_Size size, AP4_ByteStream& stream); + // methods AP4_IsfmAtom(bool m_SelectiveEncryption, AP4_UI08 m_KeyIndicatorLength, AP4_UI08 m_IvLength); - AP4_IsfmAtom(AP4_Size size, AP4_ByteStream& stream); virtual AP4_Atom* Clone(); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); @@ -57,6 +60,12 @@ public: AP4_UI08 GetIvLength() { return m_IvLength; } private: + // methods + AP4_IsfmAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + // members bool m_SelectiveEncryption; AP4_UI08 m_KeyIndicatorLength; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsltAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsltAtom.cpp new file mode 100644 index 000000000..686e68e00 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsltAtom.cpp @@ -0,0 +1,78 @@ +/***************************************************************** +| +| AP4 - iSLT Atom +| +| 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 "Ap4Utils.h" +#include "Ap4IsltAtom.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_IsltAtom) + +/*---------------------------------------------------------------------- +| AP4_IsltAtom::AP4_IsltAtom ++---------------------------------------------------------------------*/ +AP4_IsltAtom::AP4_IsltAtom(const AP4_UI08* salt) : + AP4_Atom(AP4_ATOM_TYPE_ISLT, AP4_ATOM_HEADER_SIZE+8) +{ + for (unsigned int i=0; i<8; i++) { + m_Salt[i] = salt[i]; + } +} + +/*---------------------------------------------------------------------- +| AP4_IsltAtom::AP4_IsltAtom ++---------------------------------------------------------------------*/ +AP4_IsltAtom::AP4_IsltAtom(AP4_UI32 size, AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_ISLT, size) +{ + stream.Read((void*)m_Salt, 8); +} + +/*---------------------------------------------------------------------- +| AP4_IsltAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IsltAtom::WriteFields(AP4_ByteStream& stream) +{ + return stream.Write((const void*)m_Salt, 8); +} + +/*---------------------------------------------------------------------- +| AP4_IsltAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IsltAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("salt", m_Salt, 8); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UnknownDescriptor.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsltAtom.h index 60d5f5ae4..949251acb 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UnknownDescriptor.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsltAtom.h @@ -1,8 +1,8 @@ /***************************************************************** | -| AP4 - Unknown Descriptor +| AP4 - iSLT Atom | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -26,35 +26,43 @@ | ****************************************************************/ -#ifndef _AP4_UNKNOWN_DESCRIPTOR_H_ -#define _AP4_UNKNOWN_DESCRIPTOR_H_ +#ifndef _AP4_ISLT_ATOM_H_ +#define _AP4_ISLT_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4List.h" -#include "Ap4DataBuffer.h" -#include "Ap4Descriptor.h" +#include "Ap4Types.h" +#include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_UnknownDescriptor +| AP4_IsltAtom +---------------------------------------------------------------------*/ -class AP4_UnknownDescriptor : public AP4_Descriptor +class AP4_IsltAtom : public AP4_Atom { public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_IsltAtom, AP4_Atom) + + // class methods + static AP4_IsltAtom* Create(AP4_Size size, AP4_ByteStream& stream) { + if (size != AP4_ATOM_HEADER_SIZE+8) return NULL; + return new AP4_IsltAtom(size, stream); + } + // methods - AP4_UnknownDescriptor(AP4_ByteStream& stream, - unsigned char tag, - AP4_Size header_size, - AP4_Size payload_size); + AP4_IsltAtom(const AP4_UI08* salt); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); - + + // accessors + const AP4_UI08* GetSalt() { return m_Salt; } + private: + // methods + AP4_IsltAtom(AP4_UI32 size, AP4_ByteStream& stream); + // members - AP4_DataBuffer m_Data; + AP4_UI08 m_Salt[8]; }; - -#endif // _AP4_UNKNOWN_DESCRIPTOR_H_ +#endif // _AP4_ISLT_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsmaCryp.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsmaCryp.cpp index 22b24a37b..b07948e75 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsmaCryp.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsmaCryp.cpp @@ -1,8 +1,8 @@ /***************************************************************** | -| AP4 - Sample Description Objects +| AP4 - ISMA E&A Support | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,7 +27,7 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4IsmaCryp.h" #include "Ap4SchmAtom.h" @@ -38,211 +38,87 @@ #include "Ap4FrmaAtom.h" #include "Ap4IkmsAtom.h" #include "Ap4IsfmAtom.h" +#include "Ap4IsltAtom.h" #include "Ap4Utils.h" #include "Ap4TrakAtom.h" /*---------------------------------------------------------------------- -| AP4_EncaSampleEntry::AP4_EncaSampleEntry +| AP4_IsmaCipher::CreateSampleDecrypter +---------------------------------------------------------------------*/ -AP4_EncaSampleEntry::AP4_EncaSampleEntry(AP4_UI32 sample_rate, - AP4_UI16 sample_size, - AP4_UI16 channel_count, - AP4_EsDescriptor* descriptor) : -AP4_AudioSampleEntry(AP4_ATOM_TYPE_ENCA, - descriptor, - sample_rate, - sample_size, - channel_count) +AP4_Result +AP4_IsmaCipher::CreateSampleDecrypter(AP4_ProtectedSampleDescription* sample_description, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_IsmaCipher*& decrypter) { -} - -/*---------------------------------------------------------------------- -| 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 scheme info - AP4_SchmAtom* schm = (AP4_SchmAtom*)FindChild("sinf/schm"); - if (schm == NULL) return NULL; - - // get the sample description for the original sample entry - AP4_MpegAudioSampleDescription* original_sample_description = - (AP4_MpegAudioSampleDescription*) - AP4_AudioSampleEntry::ToSampleDescription(); - - // get the schi atom - AP4_ContainerAtom* schi; - schi = static_cast<AP4_ContainerAtom*>(FindChild("sinf/schi")); - - // create the sample description - return DNew AP4_IsmaCrypSampleDescription( - original_sample_description, - frma?frma->GetOriginalFormat():AP4_ATOM_TYPE_MP4A, - schm->GetSchemeType(), - schm->GetSchemeVersion(), - schm->GetSchemeUri().c_str(), - schi); -} - -/*---------------------------------------------------------------------- -| AP4_EncvSampleEntry::AP4_EncaSampleEntry -+---------------------------------------------------------------------*/ -AP4_EncvSampleEntry::AP4_EncvSampleEntry(AP4_UI16 width, - AP4_UI16 height, - AP4_UI16 depth, - const char* compressor_name, - AP4_EsDescriptor* descriptor) : - AP4_VisualSampleEntry(AP4_ATOM_TYPE_ENCV, - descriptor, - width, - height, - depth, - compressor_name) -{ -} - -/*---------------------------------------------------------------------- -| 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 scheme info - AP4_SchmAtom* schm = (AP4_SchmAtom*)FindChild("sinf/schm"); - if (schm == NULL) return NULL; - - // get the sample description for the original sample entry - AP4_MpegVideoSampleDescription* original_sample_description = - (AP4_MpegVideoSampleDescription*) - AP4_VisualSampleEntry::ToSampleDescription(); - - // get the schi atom - AP4_ContainerAtom* schi; - schi = static_cast<AP4_ContainerAtom*>(FindChild("sinf/schi")); - - // create the sample description - return DNew AP4_IsmaCrypSampleDescription( - original_sample_description, - frma?frma->GetOriginalFormat():AP4_ATOM_TYPE_MP4V, - schm->GetSchemeType(), - schm->GetSchemeVersion(), - schm->GetSchemeUri().c_str(), - schi); -} - -/*---------------------------------------------------------------------- -| AP4_IsmaCrypSampleDescription::AP4_IsmaCrypSampleDescription -+---------------------------------------------------------------------*/ -AP4_IsmaCrypSampleDescription::AP4_IsmaCrypSampleDescription( - AP4_MpegSampleDescription* original_sample_description, - AP4_UI32 original_format, - AP4_UI32 scheme_type, - AP4_UI32 scheme_version, - const char* scheme_uri, - AP4_ContainerAtom* schi) : - AP4_SampleDescription(TYPE_ISMACRYP), - m_OriginalSampleDescription(original_sample_description), - m_OriginalFormat(original_format), - m_SchemeType(scheme_type), - m_SchemeVersion(scheme_version), - m_SchemeUri(scheme_uri) -{ - m_SchemeInfo = DNew AP4_IsmaCrypSchemeInfo(schi); -} - -/*---------------------------------------------------------------------- -| AP4_IsmaCrypSampleDescription::~AP4_IsmaCrypSampleDescription -+---------------------------------------------------------------------*/ -AP4_IsmaCrypSampleDescription::~AP4_IsmaCrypSampleDescription() -{ - delete m_SchemeInfo; - delete m_OriginalSampleDescription; -} + // check parameters + if (key == NULL || block_cipher_factory == NULL) { + return AP4_ERROR_INVALID_PARAMETERS; + } + decrypter = NULL; + + // create the cipher + AP4_BlockCipher* block_cipher = NULL; + AP4_Result result = block_cipher_factory->Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::ENCRYPT, + key, + key_size, + block_cipher); + if (AP4_FAILED(result)) return result; -/*---------------------------------------------------------------------- -| AP4_IsmaCrypSampleDescription::ToAtom -+---------------------------------------------------------------------*/ -AP4_Atom* -AP4_IsmaCrypSampleDescription::ToAtom() const -{ - // TODO: not implemented yet - return NULL; -} + // get the scheme info atom + AP4_ContainerAtom* schi = sample_description->GetSchemeInfo()->GetSchiAtom(); + if (schi == NULL) return AP4_ERROR_INVALID_FORMAT; -/*---------------------------------------------------------------------- -| AP4_IsmaCrypSchemeInfo::AP4_IsmaCrypSchemeInfo -+---------------------------------------------------------------------*/ -AP4_IsmaCrypSchemeInfo::AP4_IsmaCrypSchemeInfo(AP4_ContainerAtom* schi) : - m_SchiAtom(AP4_ATOM_TYPE_SCHI) -{ - if (schi) { - AP4_List<AP4_Atom>& children = schi->GetChildren(); - AP4_List<AP4_Atom>::Item* child_item = children.FirstItem(); - while (child_item) { - AP4_Atom* child_atom = child_item->GetData(); - AP4_Atom* clone = child_atom->Clone(); - if (clone) m_SchiAtom.AddChild(clone); - child_item = child_item->GetNext(); - } - } + // get the cipher params + AP4_IsfmAtom* isfm = AP4_DYNAMIC_CAST(AP4_IsfmAtom, schi->FindChild("iSFM")); + if (isfm == NULL) return AP4_ERROR_INVALID_FORMAT; + + // get the salt + AP4_IsltAtom* salt = AP4_DYNAMIC_CAST(AP4_IsltAtom, schi->FindChild("iSLT")); + + // instantiate the decrypter + decrypter = new AP4_IsmaCipher(block_cipher, + salt?salt->GetSalt():NULL, + isfm->GetIvLength(), + isfm->GetKeyIndicatorLength(), + isfm->GetSelectiveEncryption()); + return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_IsmaCrypCipher::AP4_IsmaCipher +| AP4_IsmaCrypCipher::AP4_IsmaCipher +---------------------------------------------------------------------*/ -AP4_IsmaCipher::AP4_IsmaCipher(const AP4_UI08* key, - const AP4_UI08* salt, - AP4_Size iv_length, - AP4_Size key_indicator_length, - bool selective_encryption) : +AP4_IsmaCipher::AP4_IsmaCipher(AP4_BlockCipher* block_cipher, + const AP4_UI08* salt, + AP4_UI08 iv_length, + AP4_UI08 key_indicator_length, + bool selective_encryption) : m_IvLength(iv_length), m_KeyIndicatorLength(key_indicator_length), m_SelectiveEncryption(selective_encryption) { - // NOTE: we do not handle key indicators yey, so there is only one key. + // NOTE: we do not handle key indicators yet, so there is only one key. // left-align the salt - unsigned char salt_128[AP4_ISMACRYP_IAEC_KEY_LENGTH]; - for (unsigned int i=0; i<8; i++) { - salt_128[i] = salt[i]; + unsigned char salt_128[AP4_CIPHER_BLOCK_SIZE]; + unsigned int i=0; + if (salt) { + for (; i<8; i++) { + salt_128[i] = salt[i]; + } } - for (unsigned int i=0; i<8; i++) { - salt_128[8+i] = 0; + for (; i<AP4_CIPHER_BLOCK_SIZE; i++) { + salt_128[i] = 0; } // create a cipher - m_Cipher = DNew AP4_StreamCipher(key, salt_128); + m_Cipher = new AP4_CtrStreamCipher(block_cipher, salt_128, iv_length); } /*---------------------------------------------------------------------- -| AP4_IsmaCipher::~AP4_IsmaCipher +| AP4_IsmaCipher::~AP4_IsmaCipher +---------------------------------------------------------------------*/ AP4_IsmaCipher::~AP4_IsmaCipher() { @@ -250,71 +126,87 @@ AP4_IsmaCipher::~AP4_IsmaCipher() } /*---------------------------------------------------------------------- -| AP4_IsmaCipher::DecryptSample +| AP4_IsmaCipher::GetDecryptedSampleSize +---------------------------------------------------------------------*/ -AP4_Result -AP4_IsmaCipher::DecryptSample(AP4_DataBuffer& data_in, - AP4_DataBuffer& data_out) +AP4_Size +AP4_IsmaCipher::GetDecryptedSampleSize(AP4_Sample& sample) { - bool is_encrypted = true; - const unsigned char* in = data_in.GetData(); + AP4_Size isma_header_size = m_KeyIndicatorLength + m_IvLength; if (m_SelectiveEncryption) { - is_encrypted = ((in[0]&1)==1); - in++; + ++isma_header_size; } + return sample.GetSize()-isma_header_size; +} - // get the IV (this implementation only supports un to 32 bits of IV) - // so we skip anything beyond the last 4 bytes - unsigned int to_read = m_IvLength; - if (to_read > 16 || to_read == 0) return AP4_ERROR_INVALID_FORMAT; - while (to_read > 4) { - to_read--; - in++; - } - AP4_UI32 iv = 0; - while (to_read--) { - iv = (iv<<8) | *in++; - } +/*---------------------------------------------------------------------- +| AP4_IsmaCipher::DecryptSampleData ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IsmaCipher::DecryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out) +{ + bool is_encrypted = true; + const AP4_UI08* in = data_in.GetData(); + AP4_Size in_size = data_in.GetDataSize(); + AP4_Size header_size; + + // default to 0 output + data_out.SetDataSize(0); - // get the key indicator (we only support up to 32 bits as well) - to_read = m_KeyIndicatorLength; - if (to_read > 4 ) return AP4_ERROR_INVALID_FORMAT; - while (to_read > 4) { - to_read--; + // check the selective encryption flag + if (in_size < 1) return AP4_ERROR_INVALID_FORMAT; + if (m_SelectiveEncryption) { + is_encrypted = ((in[0]&0x80)!=0); in++; } - AP4_UI32 key_indicator = 0; - while (to_read--) { - key_indicator = (key_indicator<<8) | *in++; - } - // we only support key indicator = 0 for now... (TODO) - if (key_indicator != 0) { - return AP4_FAILURE; - } + + // check the header size + header_size = (m_SelectiveEncryption?1:0)+ + (is_encrypted?m_KeyIndicatorLength+m_IvLength:0); + if (header_size > in_size) return AP4_ERROR_INVALID_FORMAT; // process the sample data - unsigned int header_size = in-data_in.GetData(); - unsigned int payload_size = data_in.GetDataSize()-header_size; + AP4_Size payload_size = in_size-header_size; data_out.SetDataSize(payload_size); - unsigned char* out = data_out.UseData(); + AP4_UI08* out = data_out.UseData(); if (is_encrypted) { - m_Cipher->SetStreamOffset(iv); - m_Cipher->ProcessBuffer(in, out, payload_size); + // get the IV + const AP4_UI08* iv = in; + in += m_IvLength; + + // get the key indicator (we only support up to 32 bits) + unsigned int to_read = m_KeyIndicatorLength; + while (to_read > 4) { + // skip anything above 4 bytes + to_read--; + in++; + } + AP4_UI32 key_indicator = 0; + while (to_read--) { + key_indicator = (key_indicator<<8) | *in++; + header_size++; + } + // we only support key indicator = 0 for now... (TODO) + if (key_indicator != 0) { + return AP4_ERROR_NOT_SUPPORTED; + } + + m_Cipher->SetIV(iv); + m_Cipher->ProcessBuffer(in, payload_size, out); } else { - memcpy(out, in, payload_size); + AP4_CopyMemory(out, in, payload_size); } return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_IsmaCipher::EncryptSample +| AP4_IsmaCipher::EncryptSampleData +---------------------------------------------------------------------*/ AP4_Result -AP4_IsmaCipher::EncryptSample(AP4_DataBuffer& data_in, - AP4_DataBuffer& data_out, - AP4_Offset iv, - bool skip_encryption) +AP4_IsmaCipher::EncryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out, + AP4_UI32 iv) { // setup the buffers const unsigned char* in = data_in.GetData(); @@ -323,66 +215,57 @@ AP4_IsmaCipher::EncryptSample(AP4_DataBuffer& data_in, // IV on 4 bytes AP4_BytesFromUInt32BE(out, iv); - out += 4; // encrypt the payload - m_Cipher->SetStreamOffset(iv); - m_Cipher->ProcessBuffer(in, out, data_in.GetDataSize()); + m_Cipher->SetIV(out); + AP4_Size data_size = data_in.GetDataSize(); + m_Cipher->ProcessBuffer(in, data_size, out+4); - return AP4_FAILURE; + return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_IsmaTrackDecrypter +| AP4_IsmaTrackDecrypter::Create +---------------------------------------------------------------------*/ -class AP4_IsmaTrackDecrypter : public AP4_Processor::TrackHandler { -public: - // constructor - AP4_IsmaTrackDecrypter(const AP4_UI08* key, - const AP4_UI08* salt, - AP4_IsmaCrypSampleDescription* sample_description, - AP4_SampleEntry* sample_entry); - virtual ~AP4_IsmaTrackDecrypter(); - - // methods - virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample); - virtual AP4_Result ProcessTrack(); - virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in, - AP4_DataBuffer& data_out); +AP4_Result +AP4_IsmaTrackDecrypter::Create(const AP4_UI08* key, + AP4_Size key_size, + AP4_ProtectedSampleDescription* sample_description, + AP4_SampleEntry* sample_entry, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_IsmaTrackDecrypter*& decrypter) +{ + // instantiate the cipher + AP4_IsmaCipher* cipher = NULL; + decrypter = NULL; + AP4_Result result = AP4_IsmaCipher::CreateSampleDecrypter(sample_description, + key, + key_size, + block_cipher_factory, + cipher); + if (AP4_FAILED(result)) return result; -private: - // members - AP4_IsfmAtom* m_CipherParams; - AP4_IsmaCipher* m_Cipher; - AP4_SampleEntry* m_SampleEntry; - AP4_UI32 m_OriginalFormat; -}; + // instanciate the object + decrypter = new AP4_IsmaTrackDecrypter(cipher, + sample_entry, + sample_description->GetOriginalFormat()); + return AP4_SUCCESS; +} /*---------------------------------------------------------------------- -| AP4_IsmaTrackDecrypter::AP4_IsmaTrackDecrypter +| AP4_IsmaTrackDecrypter::AP4_IsmaTrackDecrypter +---------------------------------------------------------------------*/ -AP4_IsmaTrackDecrypter::AP4_IsmaTrackDecrypter( - const AP4_UI08* key, - const AP4_UI08* salt, - AP4_IsmaCrypSampleDescription* sample_description, - AP4_SampleEntry* sample_entry) : - m_SampleEntry(sample_entry) +AP4_IsmaTrackDecrypter::AP4_IsmaTrackDecrypter(AP4_IsmaCipher* cipher, + AP4_SampleEntry* sample_entry, + AP4_UI32 original_format) : + m_Cipher(cipher), + m_SampleEntry(sample_entry), + m_OriginalFormat(original_format) { - // get the cipher params - m_CipherParams = (AP4_IsfmAtom*)sample_description->GetSchemeInfo()->GetSchiAtom().FindChild("iSFM"); - - // instantiate the cipher - m_Cipher = DNew AP4_IsmaCipher(key, salt, - m_CipherParams->GetIvLength(), - m_CipherParams->GetKeyIndicatorLength(), - m_CipherParams->GetSelectiveEncryption()); - - // get the sample entry details - m_OriginalFormat = sample_description->GetOriginalFormat(); } /*---------------------------------------------------------------------- -| AP4_IsmaTrackDecrypter::~AP4_IsmaTrackDecrypter +| AP4_IsmaTrackDecrypter::~AP4_IsmaTrackDecrypter +---------------------------------------------------------------------*/ AP4_IsmaTrackDecrypter::~AP4_IsmaTrackDecrypter() { @@ -390,22 +273,16 @@ AP4_IsmaTrackDecrypter::~AP4_IsmaTrackDecrypter() } /*---------------------------------------------------------------------- -| AP4_IsmaTrackDecrypter::GetProcessedSampleSize +| AP4_IsmaTrackDecrypter::GetProcessedSampleSize +---------------------------------------------------------------------*/ AP4_Size AP4_IsmaTrackDecrypter::GetProcessedSampleSize(AP4_Sample& sample) { - AP4_Size isma_header_size = - m_CipherParams->GetKeyIndicatorLength() + - m_CipherParams->GetIvLength(); - if (m_CipherParams->GetSelectiveEncryption()) { - isma_header_size++; - } - return sample.GetSize()-isma_header_size; + return m_Cipher->GetDecryptedSampleSize(sample); } /*---------------------------------------------------------------------- -| AP4_IsmaTrackDecrypter::ProcessTrack +| AP4_IsmaTrackDecrypter::ProcessTrack +---------------------------------------------------------------------*/ AP4_Result AP4_IsmaTrackDecrypter::ProcessTrack() @@ -416,56 +293,23 @@ AP4_IsmaTrackDecrypter::ProcessTrack() } /*---------------------------------------------------------------------- -| AP4_IsmaDecrypter::ProcessSample +| AP4_IsmaDecrypter::ProcessSample +---------------------------------------------------------------------*/ AP4_Result AP4_IsmaTrackDecrypter::ProcessSample(AP4_DataBuffer& data_in, AP4_DataBuffer& data_out) { - return m_Cipher->DecryptSample(data_in, data_out); -} - -/*---------------------------------------------------------------------- -| AP4_IsmaDecryptingProcessor:CreateTrackHandler -+---------------------------------------------------------------------*/ -AP4_Processor::TrackHandler* -AP4_IsmaDecryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) -{ - // find the stsd atom - AP4_StsdAtom* stsd = 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_ISMACRYP) { - // create a handler for this track - AP4_IsmaCrypSampleDescription* ismacryp_desc = - static_cast<AP4_IsmaCrypSampleDescription*>(desc); - if (ismacryp_desc->GetSchemeType() == AP4_ISMACRYP_SCHEME_TYPE_IAEC) { - const AP4_UI08* key; - const AP4_UI08* salt; - if (AP4_SUCCEEDED(m_KeyMap.GetKey(trak->GetId(), key, salt))) { - return DNew AP4_IsmaTrackDecrypter(key, salt, ismacryp_desc, entry); - } - } - } - - return NULL; + return m_Cipher->DecryptSampleData(data_in, data_out); } /*---------------------------------------------------------------------- -| AP4_IsmaTrackEncrypter +| AP4_IsmaTrackEncrypter +---------------------------------------------------------------------*/ class AP4_IsmaTrackEncrypter : public AP4_Processor::TrackHandler { public: // constructor AP4_IsmaTrackEncrypter(const char* kms_uri, - const AP4_UI08* key, + AP4_BlockCipher* block_cipher, const AP4_UI08* salt, AP4_SampleEntry* sample_entry, AP4_UI32 format); @@ -483,29 +327,29 @@ private: AP4_IsmaCipher* m_Cipher; AP4_SampleEntry* m_SampleEntry; AP4_UI32 m_Format; - AP4_Offset m_ByteOffset; + AP4_UI32 m_Counter; }; /*---------------------------------------------------------------------- -| AP4_IsmaTrackEncrypter::AP4_IsmaTrackEncrypter +| AP4_IsmaTrackEncrypter::AP4_IsmaTrackEncrypter +---------------------------------------------------------------------*/ AP4_IsmaTrackEncrypter::AP4_IsmaTrackEncrypter( const char* kms_uri, - const AP4_UI08* key, + AP4_BlockCipher* block_cipher, const AP4_UI08* salt, AP4_SampleEntry* sample_entry, AP4_UI32 format) : m_KmsUri(kms_uri), m_SampleEntry(sample_entry), m_Format(format), - m_ByteOffset(0) + m_Counter(0) { // instantiate the cipher (fixed params for now) - m_Cipher = DNew AP4_IsmaCipher(key, salt, 4, 0, false); + m_Cipher = new AP4_IsmaCipher(block_cipher, salt, 4, 0, false); } /*---------------------------------------------------------------------- -| AP4_IsmaTrackEncrypter::~AP4_IsmaTrackEncrypter +| AP4_IsmaTrackEncrypter::~AP4_IsmaTrackEncrypter +---------------------------------------------------------------------*/ AP4_IsmaTrackEncrypter::~AP4_IsmaTrackEncrypter() { @@ -513,7 +357,7 @@ AP4_IsmaTrackEncrypter::~AP4_IsmaTrackEncrypter() } /*---------------------------------------------------------------------- -| AP4_IsmaTrackEncrypter::GetProcessedSampleSize +| AP4_IsmaTrackEncrypter::GetProcessedSampleSize +---------------------------------------------------------------------*/ AP4_Size AP4_IsmaTrackEncrypter::GetProcessedSampleSize(AP4_Sample& sample) @@ -522,28 +366,32 @@ AP4_IsmaTrackEncrypter::GetProcessedSampleSize(AP4_Sample& sample) } /*---------------------------------------------------------------------- -| AP4_IsmaTrackEncrypter::ProcessTrack +| AP4_IsmaTrackEncrypter::ProcessTrack +---------------------------------------------------------------------*/ AP4_Result AP4_IsmaTrackEncrypter::ProcessTrack() { // sinf container - AP4_ContainerAtom* sinf = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_SINF); + AP4_ContainerAtom* sinf = new AP4_ContainerAtom(AP4_ATOM_TYPE_SINF); // original format - AP4_FrmaAtom* frma = DNew AP4_FrmaAtom(m_SampleEntry->GetType()); + AP4_FrmaAtom* frma = new AP4_FrmaAtom(m_SampleEntry->GetType()); // scheme - AP4_SchmAtom* schm = DNew AP4_SchmAtom(AP4_ISMACRYP_SCHEME_TYPE_IAEC, 1); + AP4_SchmAtom* schm = new AP4_SchmAtom(AP4_PROTECTION_SCHEME_TYPE_IAEC, 1); // scheme info - AP4_ContainerAtom* schi = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_SCHI); - AP4_IkmsAtom* ikms = DNew AP4_IkmsAtom(m_KmsUri.c_str()); - AP4_IsfmAtom* isfm = DNew AP4_IsfmAtom(false, 0, 4); + AP4_ContainerAtom* schi = new AP4_ContainerAtom(AP4_ATOM_TYPE_SCHI); + AP4_IkmsAtom* ikms = new AP4_IkmsAtom(m_KmsUri.GetChars()); + AP4_IsfmAtom* isfm = new AP4_IsfmAtom(m_Cipher->GetSelectiveEncryption(), + m_Cipher->GetKeyIndicatorLength(), + m_Cipher->GetIvLength()); + AP4_IsltAtom* islt = new AP4_IsltAtom(m_Cipher->GetCipher()->GetIV()); // populate the schi container schi->AddChild(ikms); schi->AddChild(isfm); + schi->AddChild(islt); // populate the sinf container sinf->AddChild(frma); @@ -560,36 +408,41 @@ AP4_IsmaTrackEncrypter::ProcessTrack() } /*---------------------------------------------------------------------- -| AP4_IsmaTrackEncrypter::ProcessSample +| AP4_IsmaTrackEncrypter::ProcessSample +---------------------------------------------------------------------*/ AP4_Result AP4_IsmaTrackEncrypter::ProcessSample(AP4_DataBuffer& data_in, AP4_DataBuffer& data_out) { - AP4_Result result = m_Cipher->EncryptSample(data_in, data_out, m_ByteOffset, false); + AP4_Result result = m_Cipher->EncryptSampleData(data_in, data_out, m_Counter); if (AP4_FAILED(result)) return result; - m_ByteOffset += data_in.GetDataSize(); + m_Counter += (data_in.GetDataSize()+AP4_CIPHER_BLOCK_SIZE-1)/AP4_CIPHER_BLOCK_SIZE; return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_IsmaEncryptingProcessor::AP4_IsmaEncryptingProcessor +| AP4_IsmaEncryptingProcessor::AP4_IsmaEncryptingProcessor +---------------------------------------------------------------------*/ -AP4_IsmaEncryptingProcessor::AP4_IsmaEncryptingProcessor(const char* kms_uri) : +AP4_IsmaEncryptingProcessor::AP4_IsmaEncryptingProcessor(const char* kms_uri, + AP4_BlockCipherFactory* block_cipher_factory) : m_KmsUri(kms_uri) { + if (block_cipher_factory == NULL) { + m_BlockCipherFactory = &AP4_DefaultBlockCipherFactory::Instance; + } else { + m_BlockCipherFactory = block_cipher_factory; + } } /*---------------------------------------------------------------------- -| AP4_IsmaEncryptingProcessor:CreateTrackHandler +| AP4_IsmaEncryptingProcessor:CreateTrackHandler +---------------------------------------------------------------------*/ AP4_Processor::TrackHandler* AP4_IsmaEncryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) { // find the stsd atom - AP4_StsdAtom* stsd = dynamic_cast<AP4_StsdAtom*>( - trak->FindChild("mdia/minf/stbl/stsd")); + 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; @@ -603,7 +456,7 @@ AP4_IsmaEncryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) const AP4_UI08* key; const AP4_UI08* salt; AP4_UI32 format = 0; - if (AP4_SUCCEEDED(m_KeyMap.GetKey(trak->GetId(), key, salt))) { + if (AP4_SUCCEEDED(m_KeyMap.GetKeyAndIv(trak->GetId(), key, salt))) { switch (entry->GetType()) { case AP4_ATOM_TYPE_MP4A: format = AP4_ATOM_TYPE_ENCA; @@ -615,8 +468,18 @@ AP4_IsmaEncryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) break; } if (format) { - return DNew AP4_IsmaTrackEncrypter(m_KmsUri.c_str(), - key, + // create the block cipher + AP4_BlockCipher* block_cipher = NULL; + AP4_Result result = m_BlockCipherFactory->Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::ENCRYPT, + key, + AP4_CIPHER_BLOCK_SIZE, + block_cipher); + if (AP4_FAILED(result)) return NULL; + + // create the encrypter + return new AP4_IsmaTrackEncrypter(m_KmsUri.GetChars(), + block_cipher, salt, entry, format); @@ -625,92 +488,3 @@ AP4_IsmaEncryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) return NULL; } - -/*---------------------------------------------------------------------- -| AP4_IsmaKeyMap::AP4_IsmaKeyMap -+---------------------------------------------------------------------*/ -AP4_IsmaKeyMap::AP4_IsmaKeyMap() -{ -} - -/*---------------------------------------------------------------------- -| AP4_IsmaKeyMap::~AP4_IsmaKeyMap -+---------------------------------------------------------------------*/ -AP4_IsmaKeyMap::~AP4_IsmaKeyMap() -{ - m_KeyEntries.DeleteReferences(); -} - -/*---------------------------------------------------------------------- -| AP4_IsmaKeyMap::SetKey -+---------------------------------------------------------------------*/ -AP4_Result -AP4_IsmaKeyMap::SetKey(AP4_UI32 track_id, const AP4_UI08* key, const AP4_UI08* salt) -{ - KeyEntry* entry = GetEntry(track_id); - if (entry == NULL) { - m_KeyEntries.Add(DNew KeyEntry(track_id, key, salt)); - } else { - entry->SetKey(key, salt); - } - - return AP4_SUCCESS; -} - -/*---------------------------------------------------------------------- -| AP4_IsmaKeyMap::GetKey -+---------------------------------------------------------------------*/ -AP4_Result -AP4_IsmaKeyMap::GetKey(AP4_UI32 track_id, const AP4_UI08*& key, const AP4_UI08*& salt) -{ - KeyEntry* entry = GetEntry(track_id); - if (entry) { - key = entry->m_Key; - salt = entry->m_Salt; - return AP4_SUCCESS; - } else { - return AP4_ERROR_NO_SUCH_ITEM; - } -} - -/*---------------------------------------------------------------------- -| AP4_IsmaKeyMap::GetEntry -+---------------------------------------------------------------------*/ -AP4_IsmaKeyMap::KeyEntry* -AP4_IsmaKeyMap::GetEntry(AP4_UI32 track_id) -{ - 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_IsmaKeyMap::KeyEntry::KeyEntry -+---------------------------------------------------------------------*/ -AP4_IsmaKeyMap::KeyEntry::KeyEntry(AP4_UI32 track_id, - const AP4_UI08* key, - const AP4_UI08* salt /* = NULL */) : - m_TrackId(track_id) -{ - SetKey(key, salt); -} - -/*---------------------------------------------------------------------- -| AP4_IsmaKeyMap::KeyEntry::SetKey -+---------------------------------------------------------------------*/ -void -AP4_IsmaKeyMap::KeyEntry::SetKey(const AP4_UI08* key, const AP4_UI08* salt) -{ - memcpy(m_Key, key, sizeof(m_Key)); - if (salt) { - memcpy(m_Salt, salt, sizeof(m_Salt)); - } else { - memset(m_Salt, 0, sizeof(m_Salt)); - } -} - diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsmaCryp.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsmaCryp.h index fd1ac7de4..159730a99 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsmaCryp.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4IsmaCryp.h @@ -1,8 +1,8 @@ /***************************************************************** | -| AP4 - Sample Description Objects +| AP4 - ISMA E&A support | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,7 +30,7 @@ #define _AP4_ISMACRYP_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Types.h" #include "Ap4SampleEntry.h" @@ -38,208 +38,112 @@ #include "Ap4AtomFactory.h" #include "Ap4SampleDescription.h" #include "Ap4Processor.h" +#include "Ap4Protection.h" /*---------------------------------------------------------------------- -| class references +| class references +---------------------------------------------------------------------*/ -class AP4_StreamCipher; +class AP4_CtrStreamCipher; +class AP4_IsfmAtom; /*---------------------------------------------------------------------- -| constants +| constants +---------------------------------------------------------------------*/ -const AP4_UI32 AP4_ISMACRYP_SCHEME_TYPE_IAEC = AP4_ATOM_TYPE('i','A','E','C'); -const AP4_Size AP4_ISMACRYP_IAEC_KEY_LENGTH = 16; +const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_IAEC = AP4_ATOM_TYPE('i','A','E','C'); /*---------------------------------------------------------------------- -| AP4_EncaSampleEntry +| AP4_IsmaCipher +---------------------------------------------------------------------*/ -class AP4_EncaSampleEntry : public AP4_AudioSampleEntry +class AP4_IsmaCipher : public AP4_SampleDecrypter { public: - // methods - AP4_EncaSampleEntry(AP4_Size size, - AP4_ByteStream& stream, - AP4_AtomFactory& atom_factory); - AP4_EncaSampleEntry(AP4_UI32 sample_rate, - AP4_UI16 sample_size, - AP4_UI16 channel_count, - AP4_EsDescriptor* descriptor); - - // methods - AP4_SampleDescription* ToSampleDescription(); -}; + // factory + static AP4_Result CreateSampleDecrypter(AP4_ProtectedSampleDescription* sample_description, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_IsmaCipher*& decrypter); -/*---------------------------------------------------------------------- -| 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_UI16 width, - AP4_UI16 height, - AP4_UI16 depth, - const char* compressor_name, - AP4_EsDescriptor* descriptor); - - // methods - AP4_SampleDescription* ToSampleDescription(); -}; - -/*---------------------------------------------------------------------- -| AP4_IsmaKeyMap -+---------------------------------------------------------------------*/ -class AP4_IsmaKeyMap -{ -public: - // constructors and destructor - AP4_IsmaKeyMap(); - ~AP4_IsmaKeyMap(); - - // methods - AP4_Result SetKey(AP4_UI32 track_id, const AP4_UI08* key, const AP4_UI08* salt = NULL); - AP4_Result GetKey(AP4_UI32 track_id, const AP4_UI08*& key, const AP4_UI08*& salt); - -private: - // types - class KeyEntry { - public: - KeyEntry(AP4_UI32 track_id, const AP4_UI08* key, const AP4_UI08* salt = NULL); - void SetKey(const AP4_UI08* key, const AP4_UI08* salt); - AP4_Ordinal m_TrackId; - AP4_UI08 m_Key[AP4_ISMACRYP_IAEC_KEY_LENGTH]; - AP4_UI08 m_Salt[AP4_ISMACRYP_IAEC_KEY_LENGTH]; - }; - - // methods - KeyEntry* GetEntry(AP4_UI32 track_id); - - // members - AP4_List<KeyEntry> m_KeyEntries; -}; - -/*---------------------------------------------------------------------- -| AP4_IsmaSchemeInfo -+---------------------------------------------------------------------*/ -class AP4_IsmaCrypSchemeInfo -{ -public: - // constructors and destructor - AP4_IsmaCrypSchemeInfo(AP4_ContainerAtom* schi); - virtual ~AP4_IsmaCrypSchemeInfo(){} - - // accessors - AP4_ContainerAtom& GetSchiAtom() { return m_SchiAtom; } - -protected: - AP4_ContainerAtom m_SchiAtom; -}; - -/*---------------------------------------------------------------------- -| AP4_IsmaCrypSampleDescription -+---------------------------------------------------------------------*/ -class AP4_IsmaCrypSampleDescription : public AP4_SampleDescription -{ -public: - // constructor and destructor - AP4_IsmaCrypSampleDescription(AP4_MpegSampleDescription* original_sample_description, - AP4_UI32 original_format, - AP4_UI32 scheme_type, - AP4_UI32 scheme_version, - const char* scheme_uri, - AP4_ContainerAtom* schi_atom); - ~AP4_IsmaCrypSampleDescription(); - - // accessors - AP4_MpegSampleDescription* GetOriginalSampleDescription() { - return m_OriginalSampleDescription; - } - AP4_UI32 GetOriginalFormat() { return m_OriginalFormat; } - AP4_UI32 GetSchemeType() { return m_SchemeType; } - AP4_UI32 GetSchemeVersion() { return m_SchemeVersion; } - AP4_String& GetSchemeUri() { return m_SchemeUri; } - AP4_IsmaCrypSchemeInfo* GetSchemeInfo() { return m_SchemeInfo; } - - // implementation of abstract base class methods - virtual AP4_Atom* ToAtom() const; - -private: - // members - AP4_MpegSampleDescription* m_OriginalSampleDescription; - AP4_UI32 m_OriginalFormat; - AP4_UI32 m_SchemeType; - AP4_UI32 m_SchemeVersion; - AP4_String m_SchemeUri; - AP4_IsmaCrypSchemeInfo* m_SchemeInfo; -}; - -/*---------------------------------------------------------------------- -| AP4_IsmaCipher -+---------------------------------------------------------------------*/ -class AP4_IsmaCipher -{ -public: // constructor and destructor - AP4_IsmaCipher(const AP4_UI08* key, - const AP4_UI08* salt, - AP4_Size iv_length, - AP4_Size key_indicator_length, - bool selective_encryption); + AP4_IsmaCipher(AP4_BlockCipher* block_cipher, + const AP4_UI08* salt, + AP4_UI08 iv_length, + AP4_UI08 key_indicator_length, + bool selective_encryption); ~AP4_IsmaCipher(); - AP4_Result EncryptSample(AP4_DataBuffer& data_in, - AP4_DataBuffer& data_out, - AP4_Offset iv, - bool skip_encryption); - AP4_Result DecryptSample(AP4_DataBuffer& data_in, - AP4_DataBuffer& data_out); + AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out, + AP4_UI32 offset); + AP4_Result DecryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out); + AP4_Size GetDecryptedSampleSize(AP4_Sample& sample); + AP4_CtrStreamCipher* GetCipher() { return m_Cipher; } + AP4_UI08 GetIvLength() { return m_IvLength; } + AP4_UI08 GetKeyIndicatorLength() { return m_KeyIndicatorLength; } + bool GetSelectiveEncryption(){ return m_SelectiveEncryption;} private: // members - AP4_StreamCipher* m_Cipher; - AP4_Size m_IvLength; - AP4_Size m_KeyIndicatorLength; - bool m_SelectiveEncryption; + AP4_CtrStreamCipher* m_Cipher; + AP4_UI08 m_IvLength; + AP4_UI08 m_KeyIndicatorLength; + bool m_SelectiveEncryption; }; /*---------------------------------------------------------------------- -| AP4_IsmaDecryptingProcessor +| AP4_IsmaTrackDecrypter +---------------------------------------------------------------------*/ -class AP4_IsmaDecryptingProcessor : public AP4_Processor -{ +class AP4_IsmaTrackDecrypter : public AP4_Processor::TrackHandler { public: - // accessors - AP4_IsmaKeyMap& GetKeyMap() { return m_KeyMap; } + // construction + static AP4_Result Create(const AP4_UI08* key, + AP4_Size key_size, + AP4_ProtectedSampleDescription* sample_description, + AP4_SampleEntry* sample_entry, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_IsmaTrackDecrypter*& decrypter); + + virtual ~AP4_IsmaTrackDecrypter(); // methods - virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak); + virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample); + virtual AP4_Result ProcessTrack(); + virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out); private: + // constructor + AP4_IsmaTrackDecrypter(AP4_IsmaCipher* cipher, + AP4_SampleEntry* sample_entry, + AP4_UI32 original_format); + // members - AP4_IsmaKeyMap m_KeyMap; + AP4_IsmaCipher* m_Cipher; + AP4_SampleEntry* m_SampleEntry; + AP4_UI32 m_OriginalFormat; }; /*---------------------------------------------------------------------- -| AP4_IsmaEncryptingProcessor +| AP4_IsmaEncryptingProcessor +---------------------------------------------------------------------*/ class AP4_IsmaEncryptingProcessor : public AP4_Processor { public: // constructors and destructor - AP4_IsmaEncryptingProcessor(const char* kms_uri); + AP4_IsmaEncryptingProcessor(const char* kms_uri, + AP4_BlockCipherFactory* block_cipher_factory = NULL); // accessors - AP4_IsmaKeyMap& GetKeyMap() { return m_KeyMap; } + AP4_ProtectionKeyMap& GetKeyMap() { return m_KeyMap; } // methods virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak); private: // members - AP4_IsmaKeyMap m_KeyMap; - AP4_String m_KmsUri; + AP4_ProtectionKeyMap m_KeyMap; + AP4_String m_KmsUri; + AP4_BlockCipherFactory* m_BlockCipherFactory; }; #endif // _AP4_ISMACRYP_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4List.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4List.h index 269986d6f..5c87f0c57 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4List.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4List.h @@ -2,7 +2,7 @@ | | AP4 - Lists | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,18 +30,18 @@ #define _AP4_LIST_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" +#include "Ap4Types.h" #include "Ap4Results.h" /*---------------------------------------------------------------------- -| forward references +| forward references +---------------------------------------------------------------------*/ template <typename T> class AP4_List; /*---------------------------------------------------------------------- -| AP4_List +| AP4_List +---------------------------------------------------------------------*/ template <typename T> class AP4_List @@ -92,18 +92,18 @@ public: AP4_Result Add(Item* item); AP4_Result Remove(T* data); AP4_Result Insert(Item* where, T* data); - AP4_Result Get(AP4_Ordinal idx, T*& data); + AP4_Result Get(AP4_Ordinal idx, T*& data) const; AP4_Result PopHead(T*& data); - AP4_Result Apply(const typename Item::Operator& op); - AP4_Result ApplyUntilFailure(const typename Item::Operator& op); - AP4_Result ApplyUntilSuccess(const typename Item::Operator& op); - AP4_Result ReverseApply(const typename Item::Operator& op); - AP4_Result Find(const typename Item::Finder& finder, T*& data); - AP4_Result ReverseFind(const typename Item::Finder& finder, T*& data); + AP4_Result Apply(const typename Item::Operator& op) const; + AP4_Result ApplyUntilFailure(const typename Item::Operator& op) const; + AP4_Result ApplyUntilSuccess(const typename Item::Operator& op) const ; + AP4_Result ReverseApply(const typename Item::Operator& op) const; + AP4_Result Find(const typename Item::Finder& finder, T*& data) const; + AP4_Result ReverseFind(const typename Item::Finder& finder, T*& data) const; AP4_Result DeleteReferences(); - AP4_Cardinal ItemCount() { return m_ItemCount; } - Item* FirstItem() { return m_Head; } - Item* LastItem() { return m_Tail; } + AP4_Cardinal ItemCount() const { return m_ItemCount; } + Item* FirstItem() const { return m_Head; } + Item* LastItem() const { return m_Tail; } protected: // members @@ -118,10 +118,10 @@ private: }; /*---------------------------------------------------------------------- -| AP4_List<T>::~AP4_List<T> +| AP4_List<T>::~AP4_List<T> +---------------------------------------------------------------------*/ template <typename T> -AP4_List<T>::~AP4_List<T>() +AP4_List<T>::~AP4_List() { Item* item = m_Head; @@ -133,18 +133,18 @@ AP4_List<T>::~AP4_List<T>() } /*---------------------------------------------------------------------- -| AP4_List<T>::Add +| AP4_List<T>::Add +---------------------------------------------------------------------*/ template <typename T> inline AP4_Result AP4_List<T>::Add(T* data) { - return Add(DNew Item(data)); + return Add(new Item(data)); } /*---------------------------------------------------------------------- -| AP4_List<T>::Add +| AP4_List<T>::Add +---------------------------------------------------------------------*/ template <typename T> AP4_Result @@ -170,7 +170,7 @@ AP4_List<T>::Add(Item* item) } /*---------------------------------------------------------------------- -| AP4_List<T>::Remove +| AP4_List<T>::Remove +---------------------------------------------------------------------*/ template <typename T> AP4_Result @@ -219,13 +219,13 @@ AP4_List<T>::Remove(T* data) } /*---------------------------------------------------------------------- -| AP4_List<T>::Insert +| AP4_List<T>::Insert +---------------------------------------------------------------------*/ template <typename T> AP4_Result AP4_List<T>::Insert(Item* where, T* data) { - Item* item = DNew Item(data); + Item* item = new Item(data); if (where == NULL) { // insert as the head @@ -263,11 +263,11 @@ AP4_List<T>::Insert(Item* where, T* data) } /*---------------------------------------------------------------------- -| AP4_List<T>::Get +| AP4_List<T>::Get +---------------------------------------------------------------------*/ template <typename T> AP4_Result -AP4_List<T>::Get(AP4_Ordinal idx, T*& data) +AP4_List<T>::Get(AP4_Ordinal idx, T*& data) const { Item* item = m_Head; @@ -282,7 +282,7 @@ AP4_List<T>::Get(AP4_Ordinal idx, T*& data) } /*---------------------------------------------------------------------- -| AP4_List<T>::PopHead +| AP4_List<T>::PopHead +---------------------------------------------------------------------*/ template <typename T> AP4_Result @@ -313,12 +313,12 @@ AP4_List<T>::PopHead(T*& data) } /*---------------------------------------------------------------------- -| AP4_List<T>::Apply +| AP4_List<T>::Apply +---------------------------------------------------------------------*/ template <typename T> inline AP4_Result -AP4_List<T>::Apply(const typename Item::Operator& op) +AP4_List<T>::Apply(const typename Item::Operator& op) const { Item* item = m_Head; @@ -331,12 +331,12 @@ AP4_List<T>::Apply(const typename Item::Operator& op) } /*---------------------------------------------------------------------- -| AP4_List<T>::ApplyUntilFailure +| AP4_List<T>::ApplyUntilFailure +---------------------------------------------------------------------*/ template <typename T> inline AP4_Result -AP4_List<T>::ApplyUntilFailure(const typename Item::Operator& op) +AP4_List<T>::ApplyUntilFailure(const typename Item::Operator& op) const { Item* item = m_Head; @@ -351,12 +351,12 @@ AP4_List<T>::ApplyUntilFailure(const typename Item::Operator& op) } /*---------------------------------------------------------------------- -| AP4_List<T>::ApplyUntilSuccess +| AP4_List<T>::ApplyUntilSuccess +---------------------------------------------------------------------*/ template <typename T> inline AP4_Result -AP4_List<T>::ApplyUntilSuccess(const typename Item::Operator& op) +AP4_List<T>::ApplyUntilSuccess(const typename Item::Operator& op) const { Item* item = m_Head; @@ -371,12 +371,12 @@ AP4_List<T>::ApplyUntilSuccess(const typename Item::Operator& op) } /*---------------------------------------------------------------------- -| AP4_List<T>::ReverseApply +| AP4_List<T>::ReverseApply +---------------------------------------------------------------------*/ template <typename T> inline AP4_Result -AP4_List<T>::ReverseApply(const typename Item::Operator& op) +AP4_List<T>::ReverseApply(const typename Item::Operator& op) const { Item* item = m_Tail; @@ -391,12 +391,12 @@ AP4_List<T>::ReverseApply(const typename Item::Operator& op) } /*---------------------------------------------------------------------- -| AP4_List<T>::Find +| AP4_List<T>::Find +---------------------------------------------------------------------*/ template <typename T> inline AP4_Result -AP4_List<T>::Find(const typename Item::Finder& finder, T*& data) +AP4_List<T>::Find(const typename Item::Finder& finder, T*& data) const { Item* item = m_Head; @@ -413,12 +413,12 @@ AP4_List<T>::Find(const typename Item::Finder& finder, T*& data) } /*---------------------------------------------------------------------- -| AP4_List<T>::ReverseFind +| AP4_List<T>::ReverseFind +---------------------------------------------------------------------*/ template <typename T> inline AP4_Result -AP4_List<T>::ReverseFind(const typename Item::Finder& finder, T*& data) +AP4_List<T>::ReverseFind(const typename Item::Finder& finder, T*& data) const { Item* item = m_Tail; @@ -435,7 +435,7 @@ AP4_List<T>::ReverseFind(const typename Item::Finder& finder, T*& data) } /*---------------------------------------------------------------------- -| AP4_List<T>::DeleteReferences +| AP4_List<T>::DeleteReferences +---------------------------------------------------------------------*/ template <typename T> inline diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Marlin.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Marlin.cpp new file mode 100644 index 000000000..66e1439c7 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Marlin.cpp @@ -0,0 +1,832 @@ +/***************************************************************** +| +| AP4 - Marlin File Format 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 "Ap4SchmAtom.h" +#include "Ap4StsdAtom.h" +#include "Ap4Sample.h" +#include "Ap4StreamCipher.h" +#include "Ap4FrmaAtom.h" +#include "Ap4Utils.h" +#include "Ap4TrakAtom.h" +#include "Ap4FtypAtom.h" +#include "Ap4IodsAtom.h" +#include "Ap4MoovAtom.h" +#include "Ap4Track.h" +#include "Ap4DescriptorFactory.h" +#include "Ap4CommandFactory.h" +#include "Ap4Marlin.h" +#include "Ap4FileByteStream.h" +#include "Ap4Ipmp.h" +#include "Ap4AesBlockCipher.h" +#include "Ap4SyntheticSampleTable.h" +#include "Ap4HdlrAtom.h" + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpAtomTypeHandler ++---------------------------------------------------------------------*/ +class AP4_MarlinIpmpAtomTypeHandler : public AP4_AtomFactory::TypeHandler +{ +public: + // constructor + AP4_MarlinIpmpAtomTypeHandler(AP4_AtomFactory* atom_factory) : + m_AtomFactory(atom_factory) {} + virtual AP4_Result CreateAtom(AP4_Atom::Type type, + AP4_UI32 size, + AP4_ByteStream& stream, + AP4_Atom::Type context, + AP4_Atom*& atom); + +private: + // members + AP4_AtomFactory* m_AtomFactory; +}; + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpAtomFactory ++---------------------------------------------------------------------*/ +class AP4_MarlinIpmpAtomFactory : public AP4_DefaultAtomFactory +{ +public: + // class members + static AP4_MarlinIpmpAtomFactory Instance; + + // constructor + AP4_MarlinIpmpAtomFactory() { + AddTypeHandler(new AP4_MarlinIpmpAtomTypeHandler(this)); + } +}; + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpAtomFactory::Instance ++---------------------------------------------------------------------*/ +AP4_MarlinIpmpAtomFactory AP4_MarlinIpmpAtomFactory::Instance; + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpAtomTypeHandler::CreateAtom ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MarlinIpmpAtomTypeHandler::CreateAtom(AP4_Atom::Type type, + AP4_UI32 size, + AP4_ByteStream& stream, + AP4_Atom::Type /*context*/, + AP4_Atom*& atom) +{ + switch (type) { + case AP4_ATOM_TYPE_SATR: + atom = AP4_ContainerAtom::Create(type, size, false, false, stream, *m_AtomFactory); + break; + + case AP4_ATOM_TYPE_STYP: + atom = new AP4_NullTerminatedStringAtom(type, size, stream); + break; + + default: + atom = NULL; + } + + return atom ? AP4_SUCCESS : AP4_FAILURE; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpParser:Parse ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MarlinIpmpParser::Parse(AP4_AtomParent& top_level, + AP4_ByteStream& stream, + AP4_List<SinfEntry>& sinf_entries, + bool remove_od_data) +{ + // check the file type + AP4_FtypAtom* ftyp = AP4_DYNAMIC_CAST(AP4_FtypAtom, top_level.GetChild(AP4_ATOM_TYPE_FTYP)); + if (ftyp == NULL || + (ftyp->GetMajorBrand() != AP4_MARLIN_BRAND_MGSV && !ftyp->HasCompatibleBrand(AP4_MARLIN_BRAND_MGSV))) { + return AP4_ERROR_INVALID_FORMAT; + } + + // check the initial object descriptor and get the OD Track ID + AP4_IodsAtom* iods = AP4_DYNAMIC_CAST(AP4_IodsAtom, top_level.FindChild("moov/iods")); + AP4_UI32 od_track_id = 0; + if (iods == NULL) return AP4_ERROR_INVALID_FORMAT; + const AP4_ObjectDescriptor* od = iods->GetObjectDescriptor(); + if (od == NULL) return AP4_ERROR_INVALID_FORMAT; + AP4_EsIdIncDescriptor* es_id_inc = AP4_DYNAMIC_CAST(AP4_EsIdIncDescriptor, od->FindSubDescriptor(AP4_DESCRIPTOR_TAG_ES_ID_INC)); + if (es_id_inc == NULL) return AP4_ERROR_INVALID_FORMAT; + od_track_id = es_id_inc->GetTrackId(); + + // find the track pointed to by the descriptor + AP4_MoovAtom* moov = AP4_DYNAMIC_CAST(AP4_MoovAtom, top_level.GetChild(AP4_ATOM_TYPE_MOOV)); + if (moov == NULL) return AP4_ERROR_INVALID_FORMAT; + AP4_TrakAtom* od_trak = NULL; + AP4_List<AP4_TrakAtom>::Item* trak_item = moov->GetTrakAtoms().FirstItem(); + while (trak_item) { + AP4_TrakAtom* trak = trak_item->GetData(); + if (trak) { + if (trak->GetId() == od_track_id) { + od_trak = trak; + } else { + sinf_entries.Add(new SinfEntry(trak->GetId(), NULL)); + } + } + trak_item = trak_item->GetNext(); + } + + // check that we have found the OD track + if (od_trak == NULL) return AP4_ERROR_INVALID_FORMAT; + + // look for the 'mpod' trak references + AP4_TrefTypeAtom* track_references; + track_references = AP4_DYNAMIC_CAST(AP4_TrefTypeAtom, od_trak->FindChild("tref/mpod")); + if (track_references == NULL) return AP4_ERROR_INVALID_FORMAT; + + // create an AP4_Track object from the trak atom and check that it has samples + AP4_Track* od_track = new AP4_Track(*od_trak, stream, 0); + if (od_track->GetSampleCount() < 1) { + delete od_track; + return AP4_ERROR_INVALID_FORMAT; + } + + // get the first sample (in this version, we only look at a single OD command) + AP4_Sample od_sample; + AP4_Result result = od_track->GetSample(0, od_sample); + if (AP4_FAILED(result)) { + delete od_track; + return AP4_ERROR_INVALID_FORMAT; + } + + // adapt the sample data into a byte stream for parsing + AP4_DataBuffer sample_data; + od_sample.ReadData(sample_data); + AP4_MemoryByteStream* sample_stream = new AP4_MemoryByteStream(sample_data); + + // look for one ObjectDescriptorUpdate command and + // one IPMP_DescriptorUpdate command + AP4_DescriptorUpdateCommand* od_update = NULL; + AP4_DescriptorUpdateCommand* ipmp_update = NULL; + do { + AP4_Command* command = NULL; + result = AP4_CommandFactory::CreateCommandFromStream(*sample_stream, command); + if (AP4_SUCCEEDED(result)) { + // found a command in the sample, check the type + switch (command->GetTag()) { + case AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_UPDATE: + if (od_update == NULL) { + od_update = AP4_DYNAMIC_CAST(AP4_DescriptorUpdateCommand, command); + } + break; + + case AP4_COMMAND_TAG_IPMP_DESCRIPTOR_UPDATE: + if (ipmp_update == NULL) { + ipmp_update = AP4_DYNAMIC_CAST(AP4_DescriptorUpdateCommand, command); + } + break; + + default: + break; + } + } + } while (AP4_SUCCEEDED(result)); + sample_stream->Release(); + sample_stream = NULL; + + // check that we have what we need + if (od_update == NULL || ipmp_update == NULL) { + delete od_track; + return AP4_ERROR_INVALID_FORMAT; + } + + // process all the object descriptors in the od update + for (AP4_List<AP4_Descriptor>::Item* od_item = od_update->GetDescriptors().FirstItem(); + od_item; + od_item = od_item->GetNext()) { + od = AP4_DYNAMIC_CAST(AP4_ObjectDescriptor, od_item->GetData()); + if (od == NULL) continue; + + // find which track this od references + AP4_EsIdRefDescriptor* es_id_ref; + es_id_ref = AP4_DYNAMIC_CAST(AP4_EsIdRefDescriptor, od->FindSubDescriptor(AP4_DESCRIPTOR_TAG_ES_ID_REF)); + if (es_id_ref == NULL || + es_id_ref->GetRefIndex() > track_references->GetTrackIds().ItemCount() || + es_id_ref->GetRefIndex() == 0) { + continue; + } + AP4_UI32 track_id = track_references->GetTrackIds()[es_id_ref->GetRefIndex()-1]; + SinfEntry* sinf_entry = NULL; + for (AP4_List<SinfEntry>::Item* sinf_entry_item = sinf_entries.FirstItem(); + sinf_entry_item; + sinf_entry_item = sinf_entry_item->GetNext()) { + sinf_entry = sinf_entry_item->GetData(); + if (sinf_entry->m_TrackId == track_id) { + break; // match + } else { + sinf_entry = NULL; // no match + } + } + if (sinf_entry == NULL) continue; // no matching entry + if (sinf_entry->m_Sinf != NULL) continue; // entry already populated + + // see what ipmp descriptor this od points to + AP4_IpmpDescriptorPointer* ipmpd_pointer; + ipmpd_pointer = AP4_DYNAMIC_CAST(AP4_IpmpDescriptorPointer, od->FindSubDescriptor(AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR_POINTER)); + if (ipmpd_pointer == NULL) continue; // no pointer + + // find the ipmp descriptor referenced by the pointer + AP4_IpmpDescriptor* ipmpd = NULL; + for (AP4_List<AP4_Descriptor>::Item* ipmpd_item = ipmp_update->GetDescriptors().FirstItem(); + ipmpd_item; + ipmpd_item = ipmpd_item->GetNext()) { + // check that this descriptor is of the right type + ipmpd = AP4_DYNAMIC_CAST(AP4_IpmpDescriptor, ipmpd_item->GetData()); + if (ipmpd == NULL || ipmpd->GetIpmpsType() != AP4_MARLIN_IPMPS_TYPE_MGSV) continue; + + // check the descriptor id + if (ipmpd->GetDescriptorId() == ipmpd_pointer->GetDescriptorId()) { + break; // match + } else { + ipmpd = NULL; // no match + } + } + if (ipmpd == NULL) continue; // no matching entry + + // parse the ipmp data into one or more 'sinf' atoms, and keep the one with the + // right type + AP4_MemoryByteStream* data = new AP4_MemoryByteStream(ipmpd->GetData().GetData(), + ipmpd->GetData().GetDataSize()); + AP4_LargeSize bytes_available = ipmpd->GetData().GetDataSize(); + do { + AP4_Atom* atom = NULL; + + // setup the factory with a context so we can instantiate an 'schm' + // atom with a slightly different format than the standard 'schm' + AP4_AtomFactory* factory = &AP4_MarlinIpmpAtomFactory::Instance; + factory->PushContext(AP4_ATOM_TYPE('m','r','l','n')); + + // parse the next atom in the stream + result = factory->CreateAtomFromStream(*data, bytes_available, atom); + factory->PopContext(); + if (AP4_FAILED(result) || atom == NULL) break; + + // check that what we have parsed is indeed an 'sinf' of the right type + if (atom->GetType() == AP4_ATOM_TYPE_SINF) { + AP4_ContainerAtom* sinf = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom); + AP4_SchmAtom* schm = AP4_DYNAMIC_CAST(AP4_SchmAtom, sinf->FindChild("schm")); + if (schm->GetSchemeType() == AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACBC && + schm->GetSchemeVersion() == 0x0100) { + // store the sinf in the entry for that track + sinf_entry->m_Sinf = sinf; + break; + } + } + delete atom; + } while (AP4_SUCCEEDED(result)); + data->Release(); + } + + // remove the iods atom and the OD track if required + if (remove_od_data) { + od_trak->Detach(); + delete od_trak; + iods->Detach(); + delete iods; + } + + // cleanup + delete od_track; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpDecryptingProcessor:AP4_MarlinIpmpDecryptingProcessor ++---------------------------------------------------------------------*/ +AP4_MarlinIpmpDecryptingProcessor::AP4_MarlinIpmpDecryptingProcessor( + 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_MarlinIpmpDecryptingProcessor::~AP4_MarlinIpmpDecryptingProcessor ++---------------------------------------------------------------------*/ +AP4_MarlinIpmpDecryptingProcessor::~AP4_MarlinIpmpDecryptingProcessor() +{ + m_SinfEntries.DeleteReferences(); +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpDecryptingProcessor:Initialize ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MarlinIpmpDecryptingProcessor::Initialize(AP4_AtomParent& top_level, + AP4_ByteStream& stream, + ProgressListener* /*listener*/) +{ + return AP4_MarlinIpmpParser::Parse(top_level, stream, m_SinfEntries, true); +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpDecryptingProcessor:CreateTrackHandler ++---------------------------------------------------------------------*/ +AP4_Processor::TrackHandler* +AP4_MarlinIpmpDecryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) +{ + // look for this track in the list of entries + AP4_MarlinIpmpParser::SinfEntry* sinf_entry = NULL; + for (AP4_List<AP4_MarlinIpmpParser::SinfEntry>::Item* sinf_entry_item = m_SinfEntries.FirstItem(); + sinf_entry_item; + sinf_entry_item = sinf_entry_item->GetNext()) { + sinf_entry = sinf_entry_item->GetData(); + if (sinf_entry->m_TrackId == trak->GetId()) { + break; // match + } else { + sinf_entry = NULL; // no match + } + } + if (sinf_entry == NULL) return NULL; // no matching entry + + // find the key + const AP4_UI08* key = m_KeyMap.GetKey(sinf_entry->m_TrackId); + if (key == NULL) return NULL; + + // create the decrypter + AP4_MarlinIpmpTrackDecrypter* decrypter = NULL; + AP4_Result result = AP4_MarlinIpmpTrackDecrypter::Create(*m_BlockCipherFactory, + key, decrypter); + if (AP4_FAILED(result)) return NULL; + + return decrypter; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackDecrypter::Create ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MarlinIpmpTrackDecrypter::Create(AP4_BlockCipherFactory& cipher_factory, + const AP4_UI08* key, + AP4_MarlinIpmpTrackDecrypter*& decrypter) +{ + // default value + decrypter = NULL; + + // create a block cipher for the decrypter + AP4_BlockCipher* block_cipher = NULL; + AP4_Result result = cipher_factory.Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::DECRYPT, + key, + AP4_AES_BLOCK_SIZE, + block_cipher); + if (AP4_FAILED(result)) return result; + + // create a CBC cipher + AP4_CbcStreamCipher* cbc_cipher = new AP4_CbcStreamCipher(block_cipher, AP4_StreamCipher::DECRYPT); + + // create the track decrypter + decrypter = new AP4_MarlinIpmpTrackDecrypter(cbc_cipher); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackDecrypter::~AP4_MarlinIpmpTrackDecrypter ++---------------------------------------------------------------------*/ +AP4_MarlinIpmpTrackDecrypter::~AP4_MarlinIpmpTrackDecrypter() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackDecrypter:GetProcessedSampleSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_MarlinIpmpTrackDecrypter::GetProcessedSampleSize(AP4_Sample& sample) +{ + // with CBC, we need to decrypt the last block to know what the padding was + AP4_Size encrypted_size = sample.GetSize()-AP4_AES_BLOCK_SIZE; + AP4_DataBuffer encrypted; + AP4_DataBuffer decrypted; + AP4_Size decrypted_size = AP4_CIPHER_BLOCK_SIZE; + if (sample.GetSize() < 2*AP4_CIPHER_BLOCK_SIZE) { + return 0; + } + AP4_Size offset = sample.GetSize()-2*AP4_CIPHER_BLOCK_SIZE; + if (AP4_FAILED(sample.ReadData(encrypted, 2*AP4_CIPHER_BLOCK_SIZE, offset))) { + return 0; + } + decrypted.Reserve(decrypted_size); + m_Cipher->SetIV(encrypted.GetData()); + if (AP4_FAILED(m_Cipher->ProcessBuffer(encrypted.GetData()+AP4_CIPHER_BLOCK_SIZE, + AP4_CIPHER_BLOCK_SIZE, + decrypted.UseData(), + &decrypted_size, + true))) { + return 0; + } + unsigned int padding_size = AP4_CIPHER_BLOCK_SIZE-decrypted_size; + return encrypted_size-padding_size; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackDecrypter:ProcessSample ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MarlinIpmpTrackDecrypter::ProcessSample(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out) +{ + AP4_Result result; + + const AP4_UI08* in = data_in.GetData(); + AP4_Size in_size = data_in.GetDataSize(); + + // default to 0 output + data_out.SetDataSize(0); + + // check that we have at least the minimum size + if (in_size < 2*AP4_AES_BLOCK_SIZE) return AP4_ERROR_INVALID_FORMAT; + + // process the sample data + AP4_Size out_size = in_size-AP4_AES_BLOCK_SIZE; // worst case + data_out.SetDataSize(out_size); + AP4_UI08* out = data_out.UseData(); + + // decrypt the data + m_Cipher->SetIV(in); + result = m_Cipher->ProcessBuffer(in+AP4_AES_BLOCK_SIZE, + in_size-AP4_AES_BLOCK_SIZE, + out, + &out_size, + true); + if (AP4_FAILED(result)) return result; + + // update the payload size + data_out.SetDataSize(out_size); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpEncryptingProcessor::AP4_MarlinIpmpEncryptingProcessor ++---------------------------------------------------------------------*/ +AP4_MarlinIpmpEncryptingProcessor::AP4_MarlinIpmpEncryptingProcessor( + 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_MarlinIpmpEncryptingProcessor::Initialize ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MarlinIpmpEncryptingProcessor::Initialize( + AP4_AtomParent& top_level, + AP4_ByteStream& /*stream*/, + AP4_Processor::ProgressListener* /*listener = NULL*/) +{ + // get the moov atom + AP4_MoovAtom* moov = AP4_DYNAMIC_CAST(AP4_MoovAtom, top_level.GetChild(AP4_ATOM_TYPE_MOOV)); + if (moov == NULL) return AP4_ERROR_INVALID_FORMAT; + + // deal with the file type + AP4_FtypAtom* ftyp = AP4_DYNAMIC_CAST(AP4_FtypAtom, top_level.GetChild(AP4_ATOM_TYPE_FTYP)); + if (ftyp) { + // remove the atom, it will be replaced with a new one + top_level.RemoveChild(ftyp); + + // keep the existing brand and compatible brands + AP4_Array<AP4_UI32> compatible_brands; + compatible_brands.EnsureCapacity(ftyp->GetCompatibleBrands().ItemCount()+1); + for (unsigned int i=0; i<ftyp->GetCompatibleBrands().ItemCount(); i++) { + compatible_brands.Append(ftyp->GetCompatibleBrands()[i]); + } + + // add the MGSV compatible brand if it is not already there + if (!ftyp->HasCompatibleBrand(AP4_MARLIN_BRAND_MGSV)) { + compatible_brands.Append(AP4_MARLIN_BRAND_MGSV); + } + + // create a replacement for the major brand + AP4_FtypAtom* new_ftyp = new AP4_FtypAtom(AP4_MARLIN_BRAND_MGSV, + 0x13c078c, //AP4_MARLIN_BRAND_MGSV_MAJOR_VERSION, + &compatible_brands[0], + compatible_brands.ItemCount()); + delete ftyp; + ftyp = new_ftyp; + } else { + AP4_UI32 isom = AP4_FTYP_BRAND_ISOM; + ftyp = new AP4_FtypAtom(AP4_MARLIN_BRAND_MGSV, 0, &isom, 1); + } + + // insert the ftyp atom as the first child + top_level.AddChild(ftyp, 0); + + // create and 'mpod' track reference atom + AP4_TrefTypeAtom* mpod = new AP4_TrefTypeAtom(AP4_ATOM_TYPE_MPOD); + + // look for an available track ID, starting at 1 + unsigned int od_track_id = 0; + unsigned int od_track_position = 0; + AP4_List<AP4_TrakAtom>::Item* trak_item = moov->GetTrakAtoms().FirstItem(); + while (trak_item) { + AP4_TrakAtom* trak = trak_item->GetData(); + if (trak) { + od_track_position++; + if (trak->GetId() >= od_track_id) { + od_track_id = trak->GetId()+1; + } + + // if the track is encrypted, reference it in the mpod + if (m_KeyMap.GetKey(trak->GetId())) { + mpod->AddTrackId(trak->GetId()); + } + + //m_SinfEntries.Add(new SinfEntry(trak->GetId(), NULL)); + } + trak_item = trak_item->GetNext(); + } + + // check that there was at least one track in the file + if (od_track_id == 0) return AP4_ERROR_INVALID_FORMAT; + + // create an initial object descriptor + AP4_InitialObjectDescriptor* iod = + // FIXME: get real values from the property map + new AP4_InitialObjectDescriptor(AP4_DESCRIPTOR_TAG_MP4_IOD, + 1022, // object descriptor id + false, + 0xFE, // OD profile level (0xFE = No OD profile specified) + 0xFF, // scene profile level + 0xFE, // audio profile level + 0xFE, // visual profile level + 0xFF); // graphics profile + + // create an ES_ID_Inc subdescriptor and add it to the initial object descriptor + AP4_EsIdIncDescriptor* es_id_inc = new AP4_EsIdIncDescriptor(od_track_id); + iod->AddSubDescriptor(es_id_inc); + + // create an iods atom to hold the initial object descriptor + AP4_IodsAtom* iods = new AP4_IodsAtom(iod); + + // add the iods atom to the moov atom (try to put it just after mvhd) + int iods_position = 0; + int item_position = 0; + for (AP4_List<AP4_Atom>::Item* item = moov->GetChildren().FirstItem(); + item; + ++item) { + ++item_position; + if (item->GetData()->GetType() == AP4_ATOM_TYPE_MVHD) { + iods_position = item_position; + break; + } + } + AP4_Result result = moov->AddChild(iods, iods_position); + if (AP4_FAILED(result)) { + delete iods; + return result; + } + + // create a sample table for the OD track + AP4_SyntheticSampleTable* od_sample_table = new AP4_SyntheticSampleTable(); + + // create the sample description for the OD track + AP4_MpegSystemSampleDescription* od_sample_description; + od_sample_description = new AP4_MpegSystemSampleDescription(AP4_STREAM_TYPE_OD, + AP4_OTI_MPEG4_SYSTEM, + NULL, + 32768, // buffer size + 1024, // max bitrate + 512); // avg bitrate + od_sample_table->AddSampleDescription(od_sample_description, true); + + // create the OD descriptor update + AP4_DescriptorUpdateCommand od_update(AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_UPDATE); + for (unsigned int i=0; i<mpod->GetTrackIds().ItemCount(); i++) { + AP4_ObjectDescriptor* od = new AP4_ObjectDescriptor(AP4_DESCRIPTOR_TAG_MP4_OD, 256+i); // descriptor id = 256+i + od->AddSubDescriptor(new AP4_EsIdRefDescriptor(i+1)); // index into mpod (1-based) + od->AddSubDescriptor(new AP4_IpmpDescriptorPointer(i+1)); // descriptor id = i+1 + od_update.AddDescriptor(od); + } + + // create the IPMP descriptor update + AP4_DescriptorUpdateCommand ipmp_update(AP4_COMMAND_TAG_IPMP_DESCRIPTOR_UPDATE); + for (unsigned int i=0; i<mpod->GetTrackIds().ItemCount(); i++) { + // create the ipmp descriptor + AP4_IpmpDescriptor* ipmp_descriptor = new AP4_IpmpDescriptor(i+1, AP4_MARLIN_IPMPS_TYPE_MGSV); + + // create the sinf container + AP4_ContainerAtom* sinf = new AP4_ContainerAtom(AP4_ATOM_TYPE_SINF); + + // add the scheme type atom + sinf->AddChild(new AP4_SchmAtom(AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACBC, 0x0100, NULL, true)); + + // setup the scheme info atom + const char* content_id = m_PropertyMap.GetProperty(mpod->GetTrackIds()[i], "ContentId"); + if (content_id) { + AP4_ContainerAtom* schi = new AP4_ContainerAtom(AP4_ATOM_TYPE_SCHI); + schi->AddChild(new AP4_NullTerminatedStringAtom(AP4_ATOM_TYPE_8ID_, content_id)); + sinf->AddChild(schi); + } + + // serialize the sinf atom to a buffer and set it as the ipmp data + AP4_MemoryByteStream* sinf_data = new AP4_MemoryByteStream((AP4_Size)sinf->GetSize()); + sinf->Write(*sinf_data); + ipmp_descriptor->SetData(sinf_data->GetData(), sinf_data->GetDataSize()); + sinf_data->Release(); + + ipmp_update.AddDescriptor(ipmp_descriptor); + } + + // add the sample with the descriptors and updates + AP4_MemoryByteStream* sample_data = new AP4_MemoryByteStream(); + od_update.Write(*sample_data); + ipmp_update.Write(*sample_data); + od_sample_table->AddSample(*sample_data, 0, sample_data->GetDataSize(), 0, 0, 0, 0, true); + + // create the OD track + AP4_TrakAtom* od_track = new AP4_TrakAtom(od_sample_table, + AP4_HANDLER_TYPE_ODSM, + "Bento4 Marlin OD Handler", + od_track_id, + 0, 0, + 1, 1000, 1, 0, "und", + 0, 0); + + // add an entry in the processor's stream table to indicate that the + // media data for the OD track is not in the file stream, but in our + // memory stream. + m_ExternalTrackData.Add(new ExternalTrackData(od_track_id, sample_data)); + sample_data->Release(); + + // add a tref track reference atom + AP4_ContainerAtom* tref = new AP4_ContainerAtom(AP4_ATOM_TYPE_TREF); + tref->AddChild(mpod); + od_track->AddChild(tref, 1); // add after 'tkhd' + + // add the track to the moov atoms (just after the last track) + moov->AddChild(od_track, od_track_position); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpEncryptingProcessor::CreateTrackHandler ++---------------------------------------------------------------------*/ +AP4_Processor::TrackHandler* +AP4_MarlinIpmpEncryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) +{ + // create a handler for this track if we have a key for it + const AP4_UI08* key; + const AP4_UI08* iv; + if (AP4_SUCCEEDED(m_KeyMap.GetKeyAndIv(trak->GetId(), key, iv))) { + // create the track handler + AP4_MarlinIpmpTrackEncrypter* handler = NULL; + AP4_Result result = AP4_MarlinIpmpTrackEncrypter::Create(*m_BlockCipherFactory, key, iv, handler); + if (AP4_FAILED(result)) return NULL; + return handler; + } + + // not encrypted + return NULL; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackEncrypter::Create ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MarlinIpmpTrackEncrypter::Create(AP4_BlockCipherFactory& cipher_factory, + const AP4_UI08* key, + const AP4_UI08* iv, + AP4_MarlinIpmpTrackEncrypter*& encrypter) +{ + // default value + encrypter = NULL; + + // create a block cipher + AP4_BlockCipher* block_cipher = NULL; + AP4_Result result = cipher_factory.Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::ENCRYPT, + key, + AP4_AES_BLOCK_SIZE, + block_cipher); + if (AP4_FAILED(result)) return result; + + // create a CBC cipher + AP4_CbcStreamCipher* cbc_cipher = new AP4_CbcStreamCipher(block_cipher, AP4_StreamCipher::ENCRYPT); + + // create the track encrypter + encrypter = new AP4_MarlinIpmpTrackEncrypter(cbc_cipher, iv); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackEncrypter::AP4_MarlinIpmpTrackEncrypter ++---------------------------------------------------------------------*/ +AP4_MarlinIpmpTrackEncrypter::AP4_MarlinIpmpTrackEncrypter(AP4_StreamCipher* cipher, + const AP4_UI08* iv) : + m_Cipher(cipher) +{ + // copy the IV + AP4_CopyMemory(m_IV, iv, AP4_AES_BLOCK_SIZE); +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackEncrypter::~AP4_MarlinIpmpTrackEncrypter ++---------------------------------------------------------------------*/ +AP4_MarlinIpmpTrackEncrypter::~AP4_MarlinIpmpTrackEncrypter() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackEncrypter:GetProcessedSampleSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_MarlinIpmpTrackEncrypter::GetProcessedSampleSize(AP4_Sample& sample) +{ + return AP4_CIPHER_BLOCK_SIZE*(2+(sample.GetSize()/AP4_CIPHER_BLOCK_SIZE)); +} + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackEncrypter:ProcessSample ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MarlinIpmpTrackEncrypter::ProcessSample(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out) +{ + AP4_Result result; + + const AP4_UI08* in = data_in.GetData(); + AP4_Size in_size = data_in.GetDataSize(); + + // default to 0 output + data_out.SetDataSize(0); + + // process the sample data + AP4_Size out_size = AP4_CIPHER_BLOCK_SIZE*(2+(in_size/AP4_CIPHER_BLOCK_SIZE)); + data_out.SetDataSize(out_size); + AP4_UI08* out = data_out.UseData(); + + // write the IV + AP4_CopyMemory(out, m_IV, AP4_CIPHER_BLOCK_SIZE); + out_size -= AP4_CIPHER_BLOCK_SIZE; + + // encrypt the data + m_Cipher->SetIV(m_IV); + result = m_Cipher->ProcessBuffer(in, + in_size, + out+AP4_AES_BLOCK_SIZE, + &out_size, + true); + if (AP4_FAILED(result)) return result; + + // update the payload size + data_out.SetDataSize(out_size+AP4_AES_BLOCK_SIZE); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Marlin.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Marlin.h new file mode 100644 index 000000000..27c037595 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Marlin.h @@ -0,0 +1,198 @@ +/***************************************************************** +| +| AP4 - Marlin File Format 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_MARLIN_H_ +#define _AP4_MARLIN_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4SampleEntry.h" +#include "Ap4Atom.h" +#include "Ap4AtomFactory.h" +#include "Ap4SampleDescription.h" +#include "Ap4Processor.h" +#include "Ap4Protection.h" +#include "Ap4TrefTypeAtom.h" +#include "Ap4ObjectDescriptor.h" +#include "Ap4Command.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_MARLIN_BRAND_MGSV = AP4_ATOM_TYPE('M','G','S','V'); +const AP4_UI16 AP4_MARLIN_IPMPS_TYPE_MGSV = 0xA551; +const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACBC = AP4_ATOM_TYPE('A','C','B','C'); +const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACGK = AP4_ATOM_TYPE('A','C','G','K'); + +const AP4_Atom::Type AP4_ATOM_TYPE_SATR = AP4_ATOM_TYPE('s','a','t','r'); +const AP4_Atom::Type AP4_ATOM_TYPE_STYP = AP4_ATOM_TYPE('s','t','y','p'); + +const char* const AP4_MARLIN_IPMP_STYP_VIDEO = "urn:marlin:organization:sne:content-type:video"; +const char* const AP4_MARLIN_IPMP_STYP_AUDIO = "urn:marlin:organization:sne:content-type:audio"; + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpParser ++---------------------------------------------------------------------*/ +class AP4_MarlinIpmpParser +{ +public: + // types + struct SinfEntry { + SinfEntry(AP4_UI32 track_id, AP4_ContainerAtom* sinf) : + m_TrackId(track_id), m_Sinf(sinf) {} + ~SinfEntry() { delete m_Sinf; } + AP4_UI32 m_TrackId; + AP4_ContainerAtom* m_Sinf; + }; + + // methods + static AP4_Result Parse(AP4_AtomParent& top_level, + AP4_ByteStream& stream, + AP4_List<SinfEntry>& sinf_entries, + bool remove_od_data=false); + +private: + AP4_MarlinIpmpParser() {} // this class can't be instantiated +}; + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpDecryptingProcessor ++---------------------------------------------------------------------*/ +class AP4_MarlinIpmpDecryptingProcessor : public AP4_Processor +{ +public: + // constructor and destructor + AP4_MarlinIpmpDecryptingProcessor(const AP4_ProtectionKeyMap* key_map = NULL, + AP4_BlockCipherFactory* block_cipher_factory = NULL); + ~AP4_MarlinIpmpDecryptingProcessor(); + + // accessors + AP4_ProtectionKeyMap& GetKeyMap() { return m_KeyMap; } + + // methods + virtual AP4_Result Initialize(AP4_AtomParent& top_level, + AP4_ByteStream& stream, + ProgressListener* listener); + virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak); + +private: + + // members + AP4_BlockCipherFactory* m_BlockCipherFactory; + AP4_ProtectionKeyMap m_KeyMap; + AP4_List<AP4_MarlinIpmpParser::SinfEntry> m_SinfEntries; +}; + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackDecrypter ++---------------------------------------------------------------------*/ +class AP4_MarlinIpmpTrackDecrypter : public AP4_Processor::TrackHandler +{ +public: + // class methods + static AP4_Result Create(AP4_BlockCipherFactory& cipher_factory, + const AP4_UI08* key, + AP4_MarlinIpmpTrackDecrypter*& decrypter); + + // destructor + ~AP4_MarlinIpmpTrackDecrypter(); + + // AP4_Processor::TrackHandler methods + virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample); + virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out); + + +private: + // constructor + AP4_MarlinIpmpTrackDecrypter(AP4_StreamCipher* cipher) : m_Cipher(cipher) {} + + // members + AP4_StreamCipher* m_Cipher; +}; + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpEncryptingProcessor ++---------------------------------------------------------------------*/ +class AP4_MarlinIpmpEncryptingProcessor : public AP4_Processor +{ +public: + // constructor + AP4_MarlinIpmpEncryptingProcessor(const AP4_ProtectionKeyMap* key_map = NULL, + AP4_BlockCipherFactory* block_cipher_factory = NULL); + + // accessors + AP4_ProtectionKeyMap& GetKeyMap() { return m_KeyMap; } + AP4_TrackPropertyMap& GetPropertyMap() { return m_PropertyMap; } + + // AP4_Processor methods + virtual AP4_Result Initialize(AP4_AtomParent& top_level, + AP4_ByteStream& stream, + AP4_Processor::ProgressListener* listener = NULL); + virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak); + +private: + // members + AP4_BlockCipherFactory* m_BlockCipherFactory; + AP4_ProtectionKeyMap m_KeyMap; + AP4_TrackPropertyMap m_PropertyMap; +}; + +/*---------------------------------------------------------------------- +| AP4_MarlinIpmpTrackEncrypter ++---------------------------------------------------------------------*/ +class AP4_MarlinIpmpTrackEncrypter : public AP4_Processor::TrackHandler +{ +public: + // class methods + static AP4_Result Create(AP4_BlockCipherFactory& cipher_factory, + const AP4_UI08* key, + const AP4_UI08* iv, + AP4_MarlinIpmpTrackEncrypter*& encrypter); + + // destructor + ~AP4_MarlinIpmpTrackEncrypter(); + + // AP4_Processor::TrackHandler methods + virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample); + virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out); + + +private: + // constructor + AP4_MarlinIpmpTrackEncrypter(AP4_StreamCipher* cipher, const AP4_UI08* iv); + + // members + AP4_UI08 m_IV[16]; + AP4_StreamCipher* m_Cipher; +}; + +#endif // _AP4_MARLIN_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MdhdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MdhdAtom.cpp index 2e4c2bf50..78bab0b3c 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MdhdAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MdhdAtom.cpp @@ -1,172 +1,173 @@ -/*****************************************************************
-|
-| AP4 - mdhd Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4MdhdAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_MdhdAtom::AP4_MdhdAtom
-+---------------------------------------------------------------------*/
-AP4_MdhdAtom::AP4_MdhdAtom(AP4_UI64 creation_time,
- AP4_UI64 modification_time,
- AP4_UI32 time_scale,
- AP4_UI64 duration,
- const char* language) :
- AP4_Atom(AP4_ATOM_TYPE_MDHD, 20+AP4_FULL_ATOM_HEADER_SIZE, true),
- m_CreationTime(creation_time),
- m_ModificationTime(modification_time),
- m_TimeScale(time_scale),
- m_Duration(duration)
-{
- m_Language[0] = language[0];
- m_Language[1] = language[1];
- m_Language[2] = language[2];
-}
-
-/*----------------------------------------------------------------------
-| AP4_MdhdAtom::AP4_MdhdAtom
-+---------------------------------------------------------------------*/
-AP4_MdhdAtom::AP4_MdhdAtom(AP4_Size size, AP4_ByteStream& stream) :
- AP4_Atom(AP4_ATOM_TYPE_MDHD, size, true, stream),
- m_CreationTime(0),
- m_ModificationTime(0),
- m_TimeScale(0),
- m_Duration(0)
-{
- m_Language[0] = 0;
- m_Language[1] = 0;
- m_Language[2] = 0;
-
- if (m_Version == 0) {
- AP4_UI32 tmp = 0;
- stream.ReadUI32(tmp); m_CreationTime = tmp;
- stream.ReadUI32(tmp); m_ModificationTime = tmp;
- stream.ReadUI32(m_TimeScale);
- stream.ReadUI32(tmp); m_Duration = tmp;
- } else if (m_Version == 1) {
- stream.ReadUI64(m_CreationTime);
- stream.ReadUI64(m_ModificationTime);
- stream.ReadUI32(m_TimeScale);
- stream.ReadUI64(m_Duration);
- } else {
- // TODO
- }
-
- unsigned char lang[2];
- stream.Read(lang, 2, NULL);
- char l0 = ((lang[0]>>2)&0x1F);
- char l1 = (((lang[0]&0x3)<<3) | ((lang[1]>>5)&0x7));
- char l2 = ((lang[1]&0x1F));
- if (l0) {
- m_Language[0] = l0+0x60;
- }
- if (l1) {
- m_Language[1] = l1+0x60;
- }
- if (l2) {
- m_Language[2] = l2+0x60;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_MdhdAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_MdhdAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- if (m_Version == 0) {
- // we only deal with version 0 for the moment
- result = stream.WriteUI32((AP4_UI32)m_CreationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32((AP4_UI32)m_ModificationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_TimeScale);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32((AP4_UI32)m_Duration);
- if (AP4_FAILED(result)) return result;
- } else if (m_Version == 1) {
- result = stream.WriteUI64(m_CreationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI64(m_ModificationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_TimeScale);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI64(m_Duration);
- if (AP4_FAILED(result)) return result;
- } else {
- // TODO
- }
-
- // write the language
- AP4_UI08 l0 = (m_Language[0]==0)?0:(m_Language[0]-0x60);
- AP4_UI08 l1 = (m_Language[1]==0)?0:(m_Language[1]-0x60);
- AP4_UI08 l2 = (m_Language[2]==0)?0:(m_Language[2]-0x60);
- result = stream.WriteUI08(l0<<2 | l1>>3);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI08(l1<<5 | l2);
- if (AP4_FAILED(result)) return result;
-
- // pre-defined
- return stream.WriteUI16(0);
-}
-
-/*----------------------------------------------------------------------
-| AP4_MdhdAtom::GetDurationMs
-+---------------------------------------------------------------------*/
-AP4_UI32
-AP4_MdhdAtom::GetDurationMs()
-{
- return AP4_DurationMsFromUnits(m_Duration, m_TimeScale);
-}
-
-/*----------------------------------------------------------------------
-| AP4_MdhdAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_MdhdAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("timescale", m_TimeScale);
- inspector.AddField("duration", (AP4_UI32)m_Duration); // TODO
- inspector.AddField("duration(ms)", GetDurationMs());
- char language[4];
- AP4_StringFormat(language, sizeof(language),
- "%c%c%c",
- m_Language[0] ? m_Language[0]:'-',
- m_Language[1] ? m_Language[1]:'-',
- m_Language[2] ? m_Language[2]:'-');
- inspector.AddField("language", (const char*)language);
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - mdhd 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 "Ap4MdhdAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MdhdAtom) + +/*---------------------------------------------------------------------- +| AP4_MdhdAtom::Create ++---------------------------------------------------------------------*/ +AP4_MdhdAtom* +AP4_MdhdAtom::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 > 1) return NULL; + return new AP4_MdhdAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_MdhdAtom::AP4_MdhdAtom ++---------------------------------------------------------------------*/ +AP4_MdhdAtom::AP4_MdhdAtom(AP4_UI32 creation_time, + AP4_UI32 modification_time, + AP4_UI32 time_scale, + AP4_UI64 duration, + const char* language) : + AP4_Atom(AP4_ATOM_TYPE_MDHD, AP4_FULL_ATOM_HEADER_SIZE+20, 0, 0), + m_CreationTime(creation_time), + m_ModificationTime(modification_time), + m_TimeScale(time_scale), + m_Duration(duration) +{ + m_Language.Assign(language, 3); +} + +/*---------------------------------------------------------------------- +| AP4_MdhdAtom::AP4_MdhdAtom ++---------------------------------------------------------------------*/ +AP4_MdhdAtom::AP4_MdhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_MDHD, size, version, flags) +{ + if (m_Version == 0) { + AP4_UI32 creation_time; + stream.ReadUI32(creation_time); + m_CreationTime = creation_time; + AP4_UI32 modification_time; + stream.ReadUI32(modification_time); + m_ModificationTime = modification_time; + stream.ReadUI32(m_TimeScale); + AP4_UI32 duration; + stream.ReadUI32(duration); + m_Duration = duration; + } else { + stream.ReadUI64(m_CreationTime); + stream.ReadUI64(m_ModificationTime); + stream.ReadUI32(m_TimeScale); + stream.ReadUI64(m_Duration); + } + + unsigned char lang[2]; + stream.Read(lang, 2); + char l0 = ((lang[0]>>2)&0x1F); + char l1 = (((lang[0]&0x3)<<3) | ((lang[1]>>5)&0x7)); + char l2 = ((lang[1]&0x1F)); + if (l0 && l1 && l2) { + char lang_str[3] = {l0+0x60, l1+0x60, l2+0x60}; + m_Language.Assign(lang_str, 3); + } else { + m_Language.Assign("```", 3); + } +} + +/*---------------------------------------------------------------------- +| AP4_MdhdAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MdhdAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + if (m_Version == 0) { + result = stream.WriteUI32((AP4_UI32)m_CreationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32((AP4_UI32)m_ModificationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_TimeScale); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32((AP4_UI32)m_Duration); + if (AP4_FAILED(result)) return result; + } else { + result = stream.WriteUI64(m_CreationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI64(m_ModificationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_TimeScale); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI64(m_Duration); + if (AP4_FAILED(result)) return result; + } + + // write the language + AP4_UI08 l0 = m_Language[0]-0x60; + AP4_UI08 l1 = m_Language[1]-0x60; + AP4_UI08 l2 = m_Language[2]-0x60; + result = stream.WriteUI08(l0<<2 | l1>>3); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI08(l1<<5 | l2); + if (AP4_FAILED(result)) return result; + + // pre-defined + return stream.WriteUI16(0); +} + +/*---------------------------------------------------------------------- +| AP4_MdhdAtom::GetDurationMs ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_MdhdAtom::GetDurationMs() +{ + return AP4_DurationMsFromUnits(m_Duration, m_TimeScale); +} + +/*---------------------------------------------------------------------- +| AP4_MdhdAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MdhdAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("timescale", m_TimeScale); + inspector.AddField("duration", m_Duration); + inspector.AddField("duration(ms)", GetDurationMs()); + inspector.AddField("language", m_Language.GetChars()); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MdhdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MdhdAtom.h index d5e0bba63..f61ba9f6a 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MdhdAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MdhdAtom.h @@ -1,76 +1,86 @@ -/*****************************************************************
-|
-| AP4 - mdhd Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_MDHD_ATOM_H_
-#define _AP4_MDHD_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4List.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| constants
-+---------------------------------------------------------------------*/
-const AP4_UI32 AP4_MDHD_DEFAULT_GENERIC_TIMESCALE = 1000;
-const AP4_UI32 AP4_MDHD_DEFAULT_VIDEO_TIMESCALE = 90000;
-
-/*----------------------------------------------------------------------
-| AP4_MdhdAtom
-+---------------------------------------------------------------------*/
-class AP4_MdhdAtom : public AP4_Atom
-{
- public:
- // methods
- AP4_MdhdAtom(AP4_UI64 creation_time,
- AP4_UI64 modification_time,
- AP4_UI32 time_scale,
- AP4_UI64 duration,
- const char* language);
- AP4_MdhdAtom(AP4_Size size, AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
-
- AP4_UI32 GetDurationMs();
- AP4_UI64 GetDuration() { return m_Duration; }
- AP4_UI32 GetTimeScale() { return m_TimeScale; }
- AP4_String GetLanguage() { return AP4_String(m_Language, 3); }
-
- private:
- // members
- AP4_UI64 m_CreationTime;
- AP4_UI64 m_ModificationTime;
- AP4_UI32 m_TimeScale;
- AP4_UI64 m_Duration;
- char m_Language[3];
-};
-
-#endif // _AP4_MDHD_ATOM_H_
+/***************************************************************** +| +| AP4 - mdhd 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_MDHD_ATOM_H_ +#define _AP4_MDHD_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" +#include "Ap4String.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_MDHD_DEFAULT_GENERIC_TIMESCALE = 1000; +const AP4_UI32 AP4_MDHD_DEFAULT_VIDEO_TIMESCALE = 90000; + +/*---------------------------------------------------------------------- +| AP4_MdhdAtom ++---------------------------------------------------------------------*/ +class AP4_MdhdAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_MdhdAtom, AP4_Atom) + + // class methods + static AP4_MdhdAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_MdhdAtom(AP4_UI32 creation_time, + AP4_UI32 modification_time, + AP4_UI32 time_scale, + AP4_UI64 duration, + const char* language); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + AP4_UI32 GetDurationMs(); + AP4_UI64 GetDuration() { return m_Duration; } + void SetDuration(AP4_UI64 duration) { m_Duration = duration; } + AP4_UI32 GetTimeScale() { return m_TimeScale; } + void SetTimeScale(AP4_UI32 timescale) { m_TimeScale = timescale; } + const AP4_String& GetLanguage() { return m_Language; } + +private: + // methods + AP4_MdhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI64 m_CreationTime; + AP4_UI64 m_ModificationTime; + AP4_UI32 m_TimeScale; + AP4_UI64 m_Duration; + AP4_String m_Language; +}; + +#endif // _AP4_MDHD_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MfhdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MfhdAtom.cpp new file mode 100644 index 000000000..88b1eb96b --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MfhdAtom.cpp @@ -0,0 +1,87 @@ +/***************************************************************** +| +| AP4 - mfhd 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 "Ap4MfhdAtom.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| AP4_MfhdAtom::Create ++---------------------------------------------------------------------*/ +AP4_MfhdAtom* +AP4_MfhdAtom::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_MfhdAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_MfhdAtom::AP4_MfhdAtom ++---------------------------------------------------------------------*/ +AP4_MfhdAtom::AP4_MfhdAtom(AP4_UI32 sequence_number) : + AP4_Atom(AP4_ATOM_TYPE_MFHD, AP4_FULL_ATOM_HEADER_SIZE+4, 0, 0), + m_SequenceNumber(sequence_number) +{ +} + +/*---------------------------------------------------------------------- +| AP4_MfhdAtom::AP4_MfhdAtom ++---------------------------------------------------------------------*/ +AP4_MfhdAtom::AP4_MfhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_MFHD, size, version, flags) +{ + stream.ReadUI32(m_SequenceNumber); +} + +/*---------------------------------------------------------------------- +| AP4_MfhdAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MfhdAtom::WriteFields(AP4_ByteStream& stream) +{ + return stream.WriteUI32(m_SequenceNumber); +} + +/*---------------------------------------------------------------------- +| AP4_MfhdAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MfhdAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("sequence number", m_SequenceNumber); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MfhdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MfhdAtom.h new file mode 100644 index 000000000..d1c58bce5 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MfhdAtom.h @@ -0,0 +1,65 @@ +/***************************************************************** +| +| AP4 - mfhd 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_MFHD_ATOM_H_ +#define _AP4_MFHD_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_MfhdAtom ++---------------------------------------------------------------------*/ +class AP4_MfhdAtom : public AP4_Atom +{ +public: + // class methods + static AP4_MfhdAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_MfhdAtom(AP4_UI32 sequence_number); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + AP4_UI32 GetSequenceNumber() { return m_SequenceNumber; } + void SetSequenceNumber(AP4_UI32 sequence_number) { m_SequenceNumber = sequence_number; } + +private: + // methods + AP4_MfhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI32 m_SequenceNumber; +}; + +#endif // _AP4_MFHD_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MoovAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MoovAtom.cpp index 5dce78879..1ceab49ff 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MoovAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MoovAtom.cpp @@ -1,196 +1,136 @@ -/*****************************************************************
-|
-| AP4 - moov Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4MoovAtom.h"
-#include "Ap4TrakAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4DcomAtom.h"
-#include "Ap4CmvdAtom.h"
-#include "..\..\..\..\..\..\zlib\zlib.h"
-
-/*----------------------------------------------------------------------
-| AP4_TrakAtomCollector
-+---------------------------------------------------------------------*/
-class AP4_TrakAtomCollector : public AP4_List<AP4_Atom>::Item::Operator
-{
-public:
- AP4_TrakAtomCollector(AP4_List<AP4_TrakAtom>* track_atoms) :
- m_TrakAtoms(track_atoms) {}
-
- AP4_Result Action(AP4_Atom* atom) const {
- if (atom->GetType() == AP4_ATOM_TYPE_TRAK) {
- AP4_TrakAtom* trak = dynamic_cast<AP4_TrakAtom*>(atom);
- if (trak) {
- m_TrakAtoms->Add(trak);
- }
- }
- return AP4_SUCCESS;
- }
-
-private:
- AP4_List<AP4_TrakAtom>* m_TrakAtoms;
-};
-
-/*----------------------------------------------------------------------
-| AP4_MoovAtom::AP4_MoovAtom
-+---------------------------------------------------------------------*/
-AP4_MoovAtom::AP4_MoovAtom() :
- AP4_ContainerAtom(AP4_ATOM_TYPE_MOOV),
- m_TimeScale(0)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_MoovAtom::AP4_MoovAtom
-+---------------------------------------------------------------------*/
-AP4_MoovAtom::AP4_MoovAtom(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_ContainerAtom(AP4_ATOM_TYPE_MOOV, size, false, stream, atom_factory),
- m_TimeScale(0)
-{
- if(AP4_ContainerAtom* cmov = dynamic_cast<AP4_ContainerAtom*>(GetChild(AP4_ATOM_TYPE_CMOV)))
- {
- AP4_DcomAtom* dcom = dynamic_cast<AP4_DcomAtom*>(cmov->GetChild(AP4_ATOM_TYPE_DCOM));
- AP4_CmvdAtom* cmvd = dynamic_cast<AP4_CmvdAtom*>(cmov->GetChild(AP4_ATOM_TYPE_CMVD));
-
- if(dcom && dcom->GetCompressorSubType() == AP4_ATOM_TYPE('z','l','i','b') && cmvd)
- {
- const AP4_DataBuffer& data = cmvd->GetDataBuffer();
-
- z_stream d_stream;
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- int res;
-
- if(Z_OK == (res = inflateInit(&d_stream)))
- {
- d_stream.next_in = (Bytef*)data.GetData();
- d_stream.avail_in = data.GetDataSize();
-
- unsigned char* dst = NULL;
- int n = 0;
-
- do
- {
- dst = (unsigned char*)realloc(dst, ++n*1000);
- d_stream.next_out = &dst[(n-1)*1000];
- d_stream.avail_out = 1000;
-
- if(Z_OK != (res = inflate(&d_stream, Z_NO_FLUSH)) && Z_STREAM_END != res)
- {
- free(dst);
- dst = NULL;
- break;
- }
- }
- while(0 == d_stream.avail_out && 0 != d_stream.avail_in && Z_STREAM_END != res);
-
- inflateEnd(&d_stream);
-
- if(dst)
- {
- AP4_ByteStream* s = DNew AP4_MemoryByteStream(dst, d_stream.total_out);
- ReadChildren(atom_factory, *s, d_stream.total_out);
- s->Release();
- free(dst);
- }
-
- if(AP4_MoovAtom* moov = dynamic_cast<AP4_MoovAtom*>(GetChild(AP4_ATOM_TYPE_MOOV)))
- {
- AP4_List<AP4_Atom> Children;
-
- for(AP4_List<AP4_Atom>::Item* item = moov->GetChildren().FirstItem();
- item;
- item = item->GetNext())
- {
- Children.Add(item->GetData());
- }
-
- for(AP4_List<AP4_Atom>::Item* item = Children.FirstItem();
- item;
- item = item->GetNext())
- {
- AP4_Atom* atom = item->GetData();
- atom->Detach();
- atom->SetParent(this);
- m_Children.Add(atom);
- }
-
- moov->Detach();
- delete moov;
- }
- }
- }
- }
-
- // collect all trak atoms
- m_Children.Apply(AP4_TrakAtomCollector(&m_TrakAtoms));
-}
-
-/*----------------------------------------------------------------------
-| AP4_MoovAtom::OnChildAdded
-+---------------------------------------------------------------------*/
-void
-AP4_MoovAtom::OnChildAdded(AP4_Atom* atom)
-{
- // keep the atom in the list of trak atoms
- if (atom->GetType() == AP4_ATOM_TYPE_TRAK) {
- AP4_TrakAtom* trak = dynamic_cast<AP4_TrakAtom*>(atom);
- if (trak) {
- m_TrakAtoms.Add(trak);
- }
- }
-
- // call the base class implementation
- AP4_ContainerAtom::OnChildAdded(atom);
-}
-
-/*----------------------------------------------------------------------
-| AP4_MoovAtom::OnChildRemoved
-+---------------------------------------------------------------------*/
-void
-AP4_MoovAtom::OnChildRemoved(AP4_Atom* atom)
-{
- // remove the atom from the list of trak atoms
- if (atom->GetType() == AP4_ATOM_TYPE_TRAK) {
- AP4_TrakAtom* trak = dynamic_cast<AP4_TrakAtom*>(atom);
- if (trak) {
- m_TrakAtoms.Remove(trak);
- }
- }
-
- // call the base class implementation
- AP4_ContainerAtom::OnChildRemoved(atom);
-}
+/***************************************************************** +| +| AP4 - moov 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 "Ap4MoovAtom.h" +#include "Ap4TrakAtom.h" +#include "Ap4AtomFactory.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MoovAtom) + +/*---------------------------------------------------------------------- +| AP4_TrakAtomCollector ++---------------------------------------------------------------------*/ +class AP4_TrakAtomCollector : public AP4_List<AP4_Atom>::Item::Operator +{ +public: + AP4_TrakAtomCollector(AP4_List<AP4_TrakAtom>* track_atoms) : + m_TrakAtoms(track_atoms) {} + + AP4_Result Action(AP4_Atom* atom) const { + if (atom->GetType() == AP4_ATOM_TYPE_TRAK) { + AP4_TrakAtom* trak = AP4_DYNAMIC_CAST(AP4_TrakAtom, atom); + if (trak) { + m_TrakAtoms->Add(trak); + } + } + return AP4_SUCCESS; + } + +private: + AP4_List<AP4_TrakAtom>* m_TrakAtoms; +}; + +/*---------------------------------------------------------------------- +| AP4_MoovAtom::AP4_MoovAtom ++---------------------------------------------------------------------*/ +AP4_MoovAtom::AP4_MoovAtom() : + AP4_ContainerAtom(AP4_ATOM_TYPE_MOOV), + m_TimeScale(0) +{ +} + +/*---------------------------------------------------------------------- +| AP4_MoovAtom::AP4_MoovAtom ++---------------------------------------------------------------------*/ +AP4_MoovAtom::AP4_MoovAtom(AP4_UI32 size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_ContainerAtom(AP4_ATOM_TYPE_MOOV, size, false, stream, atom_factory), + m_TimeScale(0) +{ + // collect all trak atoms + m_Children.Apply(AP4_TrakAtomCollector(&m_TrakAtoms)); +} + +/*---------------------------------------------------------------------- +| AP4_MoovAtom::AdjustChunkOffsets ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MoovAtom::AdjustChunkOffsets(AP4_SI64 offset) +{ + for (AP4_List<AP4_TrakAtom>::Item* item = m_TrakAtoms.FirstItem(); + item; + item = item->GetNext()) { + AP4_TrakAtom* trak = item->GetData(); + trak->AdjustChunkOffsets(offset); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MoovAtom::OnChildAdded ++---------------------------------------------------------------------*/ +void +AP4_MoovAtom::OnChildAdded(AP4_Atom* atom) +{ + // keep the atom in the list of trak atoms + if (atom->GetType() == AP4_ATOM_TYPE_TRAK) { + AP4_TrakAtom* trak = AP4_DYNAMIC_CAST(AP4_TrakAtom, atom); + if (trak) { + m_TrakAtoms.Add(trak); + } + } + + // call the base class implementation + AP4_ContainerAtom::OnChildAdded(atom); +} + +/*---------------------------------------------------------------------- +| AP4_MoovAtom::OnChildRemoved ++---------------------------------------------------------------------*/ +void +AP4_MoovAtom::OnChildRemoved(AP4_Atom* atom) +{ + // remove the atom from the list of trak atoms + if (atom->GetType() == AP4_ATOM_TYPE_TRAK) { + AP4_TrakAtom* trak = AP4_DYNAMIC_CAST(AP4_TrakAtom, atom); + if (trak) { + m_TrakAtoms.Remove(trak); + } + } + + // call the base class implementation + AP4_ContainerAtom::OnChildRemoved(atom); +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MoovAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MoovAtom.h index 215423173..f06b2a137 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MoovAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MoovAtom.h @@ -2,7 +2,7 @@ | | AP4 - moov Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,39 +30,52 @@ #define _AP4_MOOV_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" #include "Ap4List.h" -#include "Ap4Atom.h" -#include "Ap4TrakAtom.h" #include "Ap4ContainerAtom.h" -#include "Ap4AtomFactory.h" /*---------------------------------------------------------------------- -| AP4_MoovAtom +| class references ++---------------------------------------------------------------------*/ +class AP4_AtomFactory; +class AP4_TrakAtom; + +/*---------------------------------------------------------------------- +| AP4_MoovAtom +---------------------------------------------------------------------*/ class AP4_MoovAtom : public AP4_ContainerAtom { public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_MoovAtom, AP4_ContainerAtom) + + // class methods + static AP4_MoovAtom* Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) { + return new AP4_MoovAtom(size, stream, atom_factory); + } + // methods AP4_MoovAtom(); - AP4_MoovAtom(AP4_Size size, - AP4_ByteStream& stream, - AP4_AtomFactory& atom_factory); AP4_List<AP4_TrakAtom>& GetTrakAtoms() { return m_TrakAtoms; } AP4_UI32 GetTimeScale() { return m_TimeScale; } + AP4_Result AdjustChunkOffsets(AP4_SI64 offset); // AP4_AtomParent methods void OnChildAdded(AP4_Atom* atom); void OnChildRemoved(AP4_Atom* atom); private: + // methods + AP4_MoovAtom(AP4_UI32 size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + // members AP4_List<AP4_TrakAtom> m_TrakAtoms; AP4_UI32 m_TimeScale; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Movie.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Movie.cpp index 2a2d9ea41..1b331fcb5 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Movie.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Movie.cpp @@ -1,234 +1,236 @@ -/*****************************************************************
-|
-| AP4 - Movie
-|
-| Copyright 2002-2005 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4File.h"
-#include "Ap4Atom.h"
-#include "Ap4TrakAtom.h"
-#include "Ap4MoovAtom.h"
-#include "Ap4MvhdAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Movie.h"
-
-/*----------------------------------------------------------------------
-| AP4_TrackFinderById
-+---------------------------------------------------------------------*/
-class AP4_TrackFinderById : public AP4_List<AP4_Track>::Item::Finder
-{
-public:
- AP4_TrackFinderById(AP4_UI32 track_id) : m_TrackId(track_id) {}
- AP4_Result Test(AP4_Track* track) const {
- return track->GetId() == m_TrackId ? AP4_SUCCESS : AP4_FAILURE;
- }
-private:
- AP4_UI32 m_TrackId;
-};
-
-/*----------------------------------------------------------------------
-| AP4_TrackFinderByType
-+---------------------------------------------------------------------*/
-class AP4_TrackFinderByType : public AP4_List<AP4_Track>::Item::Finder
-{
-public:
- AP4_TrackFinderByType(AP4_Track::Type type, AP4_Ordinal index = 0) :
- m_Type(type), m_Index(index) {}
- AP4_Result Test(AP4_Track* track) const {
- if (track->GetType() == m_Type && m_Index-- == 0) {
- return AP4_SUCCESS;
- } else {
- return AP4_FAILURE;
- }
- }
-private:
- AP4_Track::Type m_Type;
- mutable AP4_Ordinal m_Index;
-};
-
-/*----------------------------------------------------------------------
-| AP4_Movie::AP4_Movie
-+---------------------------------------------------------------------*/
-AP4_Movie::AP4_Movie(AP4_UI32 time_scale)
-{
- m_MoovAtom = DNew AP4_MoovAtom();
- m_MvhdAtom = DNew AP4_MvhdAtom(0, 0,
- time_scale,
- 0,
- 0x00010000,
- 0x0100);
- m_MoovAtom->AddChild(m_MvhdAtom);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Movie::AP4_Moovie
-+---------------------------------------------------------------------*/
-AP4_Movie::AP4_Movie(AP4_MoovAtom* moov, AP4_ByteStream& mdat) :
- m_MoovAtom(moov)
-{
- // ignore null atoms
- if (moov == NULL) return;
-
- // get the time scale
- AP4_UI32 time_scale;
- m_MvhdAtom = dynamic_cast<AP4_MvhdAtom*>(moov->GetChild(AP4_ATOM_TYPE_MVHD));
- if (m_MvhdAtom) {
- time_scale = m_MvhdAtom->GetTimeScale();
- } else {
- time_scale = 0;
- }
-
- // get all tracks
- AP4_List<AP4_TrakAtom>* trak_atoms;
- trak_atoms = &moov->GetTrakAtoms();
- AP4_List<AP4_TrakAtom>::Item* item = trak_atoms->FirstItem();
- while (item) {
- AP4_Track* track = DNew AP4_Track(*item->GetData(),
- mdat,
- time_scale);
- m_Tracks.Add(track);
- item = item->GetNext();
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_Movie::~AP4_Movie
-+---------------------------------------------------------------------*/
-AP4_Movie::~AP4_Movie()
-{
- m_Tracks.DeleteReferences();
- delete m_MoovAtom;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Movie::Inspect
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Movie::Inspect(AP4_AtomInspector& inspector)
-{
- // dump the moov atom
- return m_MoovAtom->Inspect(inspector);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Movie::GetTrack
-+---------------------------------------------------------------------*/
-AP4_Track*
-AP4_Movie::GetTrack(AP4_UI32 track_id)
-{
- AP4_Track* track = NULL;
- if (AP4_SUCCEEDED(m_Tracks.Find(AP4_TrackFinderById(track_id), track))) {
- return track;
- } else {
- return NULL;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_Movie::GetTrack
-+---------------------------------------------------------------------*/
-AP4_Track*
-AP4_Movie::GetTrack(AP4_Track::Type track_type, AP4_Ordinal index)
-{
- AP4_Track* track = NULL;
- if (AP4_SUCCEEDED(m_Tracks.Find(AP4_TrackFinderByType(track_type, index), track))) {
- return track;
- } else {
- return NULL;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_Movie::AddTrack
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Movie::AddTrack(AP4_Track* track)
-{
- // assign an ID to the track unless it already has one
- if (track->GetId() == 0) {
- track->SetId(m_Tracks.ItemCount()+1);
- }
-
- // if we don't have a time scale, use the one from the track
- if (m_MvhdAtom->GetTimeScale() == 0) {
- m_MvhdAtom->SetTimeScale(track->GetMediaTimeScale());
- }
-
- // adjust the parent time scale of the track
- track->SetMovieTimeScale(m_MvhdAtom->GetTimeScale());
-
- // update the movie duration
- if (m_MvhdAtom->GetDuration() < track->GetDuration()) {
- m_MvhdAtom->SetDuration(track->GetDuration());
- }
-
- // attach the track as a child
- m_MoovAtom->AddChild(track->GetTrakAtom());
- m_Tracks.Add(track);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Movie::GetTimeScale
-+---------------------------------------------------------------------*/
-AP4_UI32
-AP4_Movie::GetTimeScale()
-{
- if (m_MvhdAtom) {
- return m_MvhdAtom->GetTimeScale();
- } else {
- return 0;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_Movie::GetDuration
-+---------------------------------------------------------------------*/
-AP4_UI64
-AP4_Movie::GetDuration()
-{
- if (m_MvhdAtom) {
- return m_MvhdAtom->GetDuration();
- } else {
- return 0;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_Movie::GetDurationMs
-+---------------------------------------------------------------------*/
-AP4_Duration
-AP4_Movie::GetDurationMs()
-{
- if (m_MvhdAtom) {
- return m_MvhdAtom->GetDurationMs();
- } else {
- return 0;
- }
-}
+/***************************************************************** +| +| AP4 - Movie +| +| 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 "Ap4File.h" +#include "Ap4Atom.h" +#include "Ap4TrakAtom.h" +#include "Ap4MoovAtom.h" +#include "Ap4MvhdAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Movie.h" +#include "Ap4MetaData.h" + +/*---------------------------------------------------------------------- +| AP4_TrackFinderById ++---------------------------------------------------------------------*/ +class AP4_TrackFinderById : public AP4_List<AP4_Track>::Item::Finder +{ +public: + AP4_TrackFinderById(AP4_UI32 track_id) : m_TrackId(track_id) {} + AP4_Result Test(AP4_Track* track) const { + return track->GetId() == m_TrackId ? AP4_SUCCESS : AP4_FAILURE; + } +private: + AP4_UI32 m_TrackId; +}; + +/*---------------------------------------------------------------------- +| AP4_TrackFinderByType ++---------------------------------------------------------------------*/ +class AP4_TrackFinderByType : public AP4_List<AP4_Track>::Item::Finder +{ +public: + AP4_TrackFinderByType(AP4_Track::Type type, AP4_Ordinal index = 0) : + m_Type(type), m_Index(index) {} + AP4_Result Test(AP4_Track* track) const { + if (track->GetType() == m_Type && m_Index-- == 0) { + return AP4_SUCCESS; + } else { + return AP4_FAILURE; + } + } +private: + AP4_Track::Type m_Type; + mutable AP4_Ordinal m_Index; +}; + +/*---------------------------------------------------------------------- +| AP4_Movie::AP4_Movie ++---------------------------------------------------------------------*/ +AP4_Movie::AP4_Movie(AP4_UI32 time_scale) +{ + m_MoovAtom = new AP4_MoovAtom(); + m_MvhdAtom = new AP4_MvhdAtom(0, 0, + time_scale, + 0, + 0x00010000, + 0x0100); + m_MoovAtom->AddChild(m_MvhdAtom); +} + +/*---------------------------------------------------------------------- +| AP4_Movie::AP4_Moovie ++---------------------------------------------------------------------*/ +AP4_Movie::AP4_Movie(AP4_MoovAtom* moov, AP4_ByteStream& sample_stream, bool transfer_moov_ownership) : + m_MoovAtom(moov), + m_MoovAtomIsOwned(transfer_moov_ownership) +{ + // ignore null atoms + if (moov == NULL) return; + + // get the time scale + AP4_UI32 time_scale; + m_MvhdAtom = AP4_DYNAMIC_CAST(AP4_MvhdAtom, moov->GetChild(AP4_ATOM_TYPE_MVHD)); + if (m_MvhdAtom) { + time_scale = m_MvhdAtom->GetTimeScale(); + } else { + time_scale = 0; + } + + // get all tracks + AP4_List<AP4_TrakAtom>* trak_atoms; + trak_atoms = &moov->GetTrakAtoms(); + AP4_List<AP4_TrakAtom>::Item* item = trak_atoms->FirstItem(); + while (item) { + AP4_Track* track = new AP4_Track(*item->GetData(), + sample_stream, + time_scale); + m_Tracks.Add(track); + item = item->GetNext(); + } +} + +/*---------------------------------------------------------------------- +| AP4_Movie::~AP4_Movie ++---------------------------------------------------------------------*/ +AP4_Movie::~AP4_Movie() +{ + m_Tracks.DeleteReferences(); + if (m_MoovAtomIsOwned) delete m_MoovAtom; +} + +/*---------------------------------------------------------------------- +| AP4_Movie::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Movie::Inspect(AP4_AtomInspector& inspector) +{ + // dump the moov atom + return m_MoovAtom->Inspect(inspector); +} + +/*---------------------------------------------------------------------- +| AP4_Movie::GetTrack ++---------------------------------------------------------------------*/ +AP4_Track* +AP4_Movie::GetTrack(AP4_UI32 track_id) +{ + AP4_Track* track = NULL; + if (AP4_SUCCEEDED(m_Tracks.Find(AP4_TrackFinderById(track_id), track))) { + return track; + } else { + return NULL; + } +} + +/*---------------------------------------------------------------------- +| AP4_Movie::GetTrack ++---------------------------------------------------------------------*/ +AP4_Track* +AP4_Movie::GetTrack(AP4_Track::Type track_type, AP4_Ordinal index) +{ + AP4_Track* track = NULL; + if (AP4_SUCCEEDED(m_Tracks.Find(AP4_TrackFinderByType(track_type, index), track))) { + return track; + } else { + return NULL; + } +} + +/*---------------------------------------------------------------------- +| AP4_Movie::AddTrack ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Movie::AddTrack(AP4_Track* track) +{ + // assign an ID to the track unless it already has one + if (track->GetId() == 0) { + track->SetId(m_Tracks.ItemCount()+1); + } + + // if we don't have a time scale, use the one from the track + if (m_MvhdAtom->GetTimeScale() == 0) { + m_MvhdAtom->SetTimeScale(track->GetMediaTimeScale()); + } + + // adjust the parent time scale of the track + track->SetMovieTimeScale(m_MvhdAtom->GetTimeScale()); + + // update the movie duration + if (m_MvhdAtom->GetDuration() < track->GetDuration()) { + m_MvhdAtom->SetDuration(track->GetDuration()); + } + + // attach the track as a child + track->Attach(m_MoovAtom); + m_Tracks.Add(track); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Movie::GetTimeScale ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_Movie::GetTimeScale() +{ + if (m_MvhdAtom) { + return m_MvhdAtom->GetTimeScale(); + } else { + return 0; + } +} + +/*---------------------------------------------------------------------- +| AP4_Movie::GetDuration ++---------------------------------------------------------------------*/ +AP4_UI64 +AP4_Movie::GetDuration() +{ + if (m_MvhdAtom) { + return m_MvhdAtom->GetDuration(); + } else { + return 0; + } +} + +/*---------------------------------------------------------------------- +| AP4_Movie::GetDurationMs ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_Movie::GetDurationMs() +{ + if (m_MvhdAtom) { + return m_MvhdAtom->GetDurationMs(); + } else { + return 0; + } +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Movie.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Movie.h index fbd338b66..80d6cdb19 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Movie.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Movie.h @@ -1,70 +1,77 @@ -/*****************************************************************
-|
-| AP4 - Movie
-|
-| Copyright 2002-2005 Gilles Boccon-Gibod
-|
-|
-| 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_MOVIE_H_
-#define _AP4_MOVIE_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4MoovAtom.h"
-#include "Ap4MvhdAtom.h"
-#include "Ap4Track.h"
-#include "Ap4List.h"
-#include "Ap4ByteStream.h"
-
-/*----------------------------------------------------------------------
-| AP4_Movie
-+---------------------------------------------------------------------*/
-class AP4_Movie {
-public:
- // methods
- AP4_Movie(AP4_UI32 time_scale = 0);
- AP4_Movie(AP4_MoovAtom* moov, AP4_ByteStream& mdat);
- virtual ~AP4_Movie();
- AP4_Result Inspect(AP4_AtomInspector& inspector);
-
- AP4_MoovAtom* GetMoovAtom() { return m_MoovAtom;}
- AP4_MvhdAtom* GetMvhdAtom() { return m_MvhdAtom;}
- AP4_List<AP4_Track>& GetTracks() { return m_Tracks; }
- AP4_Track* GetTrack(AP4_UI32 track_id);
- AP4_Track* GetTrack(AP4_Track::Type type, AP4_Ordinal index = 0);
- AP4_Result AddTrack(AP4_Track* track);
- AP4_UI32 GetTimeScale();
- AP4_Duration GetDuration();
- AP4_Duration GetDurationMs();
-
-private:
- // members
- AP4_MoovAtom* m_MoovAtom;
- AP4_MvhdAtom* m_MvhdAtom;
- AP4_List<AP4_Track> m_Tracks;
-};
-
-#endif // _AP4_MOVIE_H_
+/***************************************************************** +| +| AP4 - Movie +| +| 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_MOVIE_H_ +#define _AP4_MOVIE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4MoovAtom.h" +#include "Ap4MvhdAtom.h" +#include "Ap4Track.h" +#include "Ap4List.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; +class AP4_AtomInspector; +class AP4_MetaData; + +/*---------------------------------------------------------------------- +| AP4_Movie ++---------------------------------------------------------------------*/ +class AP4_Movie { +public: + // methods + AP4_Movie(AP4_UI32 time_scale = 0); + AP4_Movie(AP4_MoovAtom* moov, AP4_ByteStream& sample_stream, bool transfer_moov_ownership = true); + virtual ~AP4_Movie(); + AP4_Result Inspect(AP4_AtomInspector& inspector); + + AP4_MoovAtom* GetMoovAtom() { return m_MoovAtom;} + AP4_MvhdAtom* GetMvhdAtom() { return m_MvhdAtom;} + AP4_List<AP4_Track>& GetTracks() { return m_Tracks; } + AP4_Track* GetTrack(AP4_UI32 track_id); + AP4_Track* GetTrack(AP4_Track::Type type, AP4_Ordinal index = 0); + AP4_Result AddTrack(AP4_Track* track); + AP4_UI32 GetTimeScale(); + AP4_UI64 GetDuration(); + AP4_UI32 GetDurationMs(); + +private: + // members + AP4_MoovAtom* m_MoovAtom; + bool m_MoovAtomIsOwned; + AP4_MvhdAtom* m_MvhdAtom; + AP4_List<AP4_Track> m_Tracks; +}; + +#endif // _AP4_MOVIE_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MvhdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MvhdAtom.cpp index c6dfd15fb..3a4e3059a 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MvhdAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MvhdAtom.cpp @@ -1,182 +1,202 @@ -/*****************************************************************
-|
-| AP4 - mvhd Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4MvhdAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_MvhdAtom::AP4_MvhdAtom
-+---------------------------------------------------------------------*/
-AP4_MvhdAtom::AP4_MvhdAtom(AP4_UI64 creation_time,
- AP4_UI64 modification_time,
- AP4_UI32 time_scale,
- AP4_UI64 duration,
- AP4_UI32 rate,
- AP4_UI16 volume) :
- AP4_Atom(AP4_ATOM_TYPE_MVHD, 96+AP4_FULL_ATOM_HEADER_SIZE, true),
- m_CreationTime(creation_time),
- m_ModificationTime(modification_time),
- m_TimeScale(time_scale),
- m_Duration(duration),
- m_Rate(rate),
- m_Volume(volume),
- m_NextTrackId(0xFFFFFFFF)
-{
- m_Matrix[0] = 0x00010000;
- m_Matrix[1] = 0;
- m_Matrix[2] = 0;
- m_Matrix[3] = 0;
- m_Matrix[4] = 0x00010000;
- m_Matrix[5] = 0;
- m_Matrix[6] = 0;
- m_Matrix[7] = 0;
- m_Matrix[8] = 0x40000000;
-
- memset(m_Reserved1, 0, sizeof(m_Reserved1));
- memset(m_Reserved2, 0, sizeof(m_Reserved2));
- memset(m_Predefined, 0, sizeof(m_Predefined));
-}
-
-/*----------------------------------------------------------------------
-| AP4_MvhdAtom::AP4_MvhdAtom
-+---------------------------------------------------------------------*/
-AP4_MvhdAtom::AP4_MvhdAtom(AP4_Size size, AP4_ByteStream& stream) :
- AP4_Atom(AP4_ATOM_TYPE_MVHD, size, true, stream)
-{
- if (m_Version == 0) {
- AP4_UI32 tmp = 0;
- stream.ReadUI32(tmp); m_CreationTime = tmp;
- stream.ReadUI32(tmp); m_ModificationTime = tmp;
- stream.ReadUI32(m_TimeScale);
- stream.ReadUI32(tmp); m_Duration = tmp;
- } else if (m_Version == 1) {
- stream.ReadUI64(m_CreationTime);
- stream.ReadUI64(m_ModificationTime);
- stream.ReadUI32(m_TimeScale);
- stream.ReadUI64(m_Duration);
- } else {
- // TODO
- }
-
- stream.ReadUI32(m_Rate);
- stream.ReadUI16(m_Volume);
- stream.Read(m_Reserved1, sizeof(m_Reserved1));
- stream.Read(m_Reserved2, sizeof(m_Reserved2));
- for (int i=0; i<9; i++) {
- stream.ReadUI32(m_Matrix[i]);
- }
- stream.Read(m_Predefined, sizeof(m_Predefined));
- stream.ReadUI32(m_NextTrackId);
-}
-
-/*----------------------------------------------------------------------
-| AP4_MvhdAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_MvhdAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- if (m_Version == 0) {
- result = stream.WriteUI32((AP4_UI32)m_CreationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32((AP4_UI32)m_ModificationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_TimeScale);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32((AP4_UI32)m_Duration);
- if (AP4_FAILED(result)) return result;
- } else if (m_Version == 1) {
- result = stream.WriteUI64(m_CreationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI64(m_ModificationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_TimeScale);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI64(m_Duration);
- if (AP4_FAILED(result)) return result;
- } else {
- // TODO
- }
-
- // rate & volume
- result = stream.WriteUI32(m_Rate);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI16(m_Volume);
- if (AP4_FAILED(result)) return result;
-
- // reserved
- result = stream.Write(m_Reserved1, sizeof(m_Reserved1));
- if (AP4_FAILED(result)) return result;
- result = stream.Write(m_Reserved2, sizeof(m_Reserved2));
- if (AP4_FAILED(result)) return result;
-
- // matrix
- for (int i=0; i<9; i++) {
- result = stream.WriteUI32(m_Matrix[i]);
- if (AP4_FAILED(result)) return result;
- }
-
- // pre-defined
- result = stream.Write(m_Predefined, sizeof(m_Predefined));
- if (AP4_FAILED(result)) return result;
-
- // next track id
- return stream.WriteUI32(m_NextTrackId);
-}
-
-/*----------------------------------------------------------------------
-| AP4_MvhdAtom::GetDurationMs
-+---------------------------------------------------------------------*/
-AP4_Duration
-AP4_MvhdAtom::GetDurationMs()
-{
- if (m_TimeScale) {
- return AP4_ConvertTime(m_Duration, m_TimeScale, 1000);
- } else {
- return 0;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_MvhdAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_MvhdAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("timescale", m_TimeScale);
- inspector.AddField("duration", (AP4_UI32)m_Duration);
- inspector.AddField("duration(ms)", (AP4_UI32)GetDurationMs());
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - mvhd 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 "Ap4MvhdAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MvhdAtom) + +/*---------------------------------------------------------------------- +| AP4_MvhdAtom::Create ++---------------------------------------------------------------------*/ +AP4_MvhdAtom* +AP4_MvhdAtom::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 > 1) return NULL; + return new AP4_MvhdAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_MvhdAtom::AP4_MvhdAtom ++---------------------------------------------------------------------*/ +AP4_MvhdAtom::AP4_MvhdAtom(AP4_UI32 creation_time, + AP4_UI32 modification_time, + AP4_UI32 time_scale, + AP4_UI32 duration, + AP4_UI32 rate, + AP4_UI16 volume) : + AP4_Atom(AP4_ATOM_TYPE_MVHD, AP4_FULL_ATOM_HEADER_SIZE+96, 0, 0), + m_CreationTime(creation_time), + m_ModificationTime(modification_time), + m_TimeScale(time_scale), + m_Duration(duration), + m_Rate(rate), + m_Volume(volume), + m_NextTrackId(0xFFFFFFFF) +{ + m_Matrix[0] = 0x00010000; + m_Matrix[1] = 0; + m_Matrix[2] = 0; + m_Matrix[3] = 0; + m_Matrix[4] = 0x00010000; + m_Matrix[5] = 0; + m_Matrix[6] = 0; + m_Matrix[7] = 0; + m_Matrix[8] = 0x40000000; + + AP4_SetMemory(m_Reserved1, 0, sizeof(m_Reserved1)); + AP4_SetMemory(m_Reserved2, 0, sizeof(m_Reserved2)); + AP4_SetMemory(m_Predefined, 0, sizeof(m_Predefined)); +} + +/*---------------------------------------------------------------------- +| AP4_MvhdAtom::AP4_MvhdAtom ++---------------------------------------------------------------------*/ +AP4_MvhdAtom::AP4_MvhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_MVHD, size, version, flags) +{ + if (m_Version == 0) { + AP4_UI32 creation_time; + stream.ReadUI32(creation_time); + m_CreationTime = creation_time; + AP4_UI32 modification_time; + stream.ReadUI32(modification_time); + m_ModificationTime = modification_time; + stream.ReadUI32(m_TimeScale); + AP4_UI32 duration; + stream.ReadUI32(duration); + m_Duration = duration; + } else { + stream.ReadUI64(m_CreationTime); + stream.ReadUI64(m_ModificationTime); + stream.ReadUI32(m_TimeScale); + stream.ReadUI64(m_Duration); + } + + stream.ReadUI32(m_Rate); + stream.ReadUI16(m_Volume); + stream.Read(m_Reserved1, sizeof(m_Reserved1)); + stream.Read(m_Reserved2, sizeof(m_Reserved2)); + for (int i=0; i<9; i++) { + stream.ReadUI32(m_Matrix[i]); + } + stream.Read(m_Predefined, sizeof(m_Predefined)); + stream.ReadUI32(m_NextTrackId); +} + +/*---------------------------------------------------------------------- +| AP4_MvhdAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MvhdAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + if (m_Version == 0) { + result = stream.WriteUI32((AP4_UI32)m_CreationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32((AP4_UI32)m_ModificationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_TimeScale); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32((AP4_UI32)m_Duration); + } else { + result = stream.WriteUI64(m_CreationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI64(m_ModificationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_TimeScale); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI64(m_Duration); + if (AP4_FAILED(result)) return result; + } + + // rate & volume + result = stream.WriteUI32(m_Rate); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI16(m_Volume); + if (AP4_FAILED(result)) return result; + + // reserved + result = stream.Write(m_Reserved1, sizeof(m_Reserved1)); + if (AP4_FAILED(result)) return result; + result = stream.Write(m_Reserved2, sizeof(m_Reserved2)); + if (AP4_FAILED(result)) return result; + + // matrix + for (int i=0; i<9; i++) { + result = stream.WriteUI32(m_Matrix[i]); + if (AP4_FAILED(result)) return result; + } + + // pre-defined + result = stream.Write(m_Predefined, sizeof(m_Predefined)); + if (AP4_FAILED(result)) return result; + + // next track id + return stream.WriteUI32(m_NextTrackId); +} + +/*---------------------------------------------------------------------- +| AP4_MvhdAtom::GetDurationMs ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_MvhdAtom::GetDurationMs() +{ + if (m_TimeScale) { + return (AP4_UI32)AP4_ConvertTime(m_Duration, m_TimeScale, 1000); + } else { + return 0; + } +} + +/*---------------------------------------------------------------------- +| AP4_MvhdAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MvhdAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("timescale", m_TimeScale); + inspector.AddField("duration", m_Duration); + inspector.AddField("duration(ms)", GetDurationMs()); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MvhdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MvhdAtom.h index b51ef174f..b3d4de11d 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MvhdAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4MvhdAtom.h @@ -1,80 +1,88 @@ -/*****************************************************************
-|
-| AP4 - mvhd Atoms
-|
-| Copyright 2002-2005 Gilles Boccon-Gibod
-|
-|
-| 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_MVHD_ATOM_H_
-#define _AP4_MVHD_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4List.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| AP4_MvhdAtom
-+---------------------------------------------------------------------*/
-class AP4_MvhdAtom : public AP4_Atom
-{
-public:
- // methods
- AP4_MvhdAtom(AP4_UI64 creation_time,
- AP4_UI64 modification_time,
- AP4_UI32 time_scale,
- AP4_UI64 duration,
- AP4_UI32 rate,
- AP4_UI16 volume);
- AP4_MvhdAtom(AP4_Size size, AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
- AP4_UI64 GetDuration() { return m_Duration; }
- void SetDuration(AP4_UI64 duration) { m_Duration = duration;}
- AP4_Duration GetDurationMs();
- AP4_UI32 GetTimeScale() { return m_TimeScale; }
- AP4_Result SetTimeScale(AP4_UI32 time_scale) {
- m_TimeScale = time_scale;
- return AP4_SUCCESS;
- }
-
-private:
- // members
- AP4_UI64 m_CreationTime;
- AP4_UI64 m_ModificationTime;
- AP4_UI32 m_TimeScale;
- AP4_UI64 m_Duration;
- AP4_UI32 m_Rate;
- AP4_UI16 m_Volume;
- AP4_UI08 m_Reserved1[2];
- AP4_UI08 m_Reserved2[8];
- AP4_UI32 m_Matrix[9];
- AP4_UI08 m_Predefined[24];
- AP4_UI32 m_NextTrackId;
-};
-
-#endif // _AP4_MVHD_ATOM_H_
+/***************************************************************** +| +| AP4 - mvhd 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_MVHD_ATOM_H_ +#define _AP4_MVHD_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4List.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_MvhdAtom ++---------------------------------------------------------------------*/ +class AP4_MvhdAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_MvhdAtom, AP4_Atom) + + // class methods + static AP4_MvhdAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_MvhdAtom(AP4_UI32 creation_time, + AP4_UI32 modification_time, + AP4_UI32 time_scale, + AP4_UI32 duration, + AP4_UI32 rate, + AP4_UI16 volume); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + AP4_UI64 GetDuration() { return m_Duration; } + void SetDuration(AP4_UI64 duration) { m_Duration = duration;} + AP4_UI32 GetDurationMs(); + AP4_UI32 GetTimeScale() { return m_TimeScale; } + AP4_Result SetTimeScale(AP4_UI32 time_scale) { + m_TimeScale = time_scale; + return AP4_SUCCESS; + } + +private: + // methods + AP4_MvhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI64 m_CreationTime; + AP4_UI64 m_ModificationTime; + AP4_UI32 m_TimeScale; + AP4_UI64 m_Duration; + AP4_UI32 m_Rate; + AP4_UI16 m_Volume; + AP4_UI08 m_Reserved1[2]; + AP4_UI08 m_Reserved2[8]; + AP4_UI32 m_Matrix[9]; + AP4_UI08 m_Predefined[24]; + AP4_UI32 m_NextTrackId; +}; + +#endif // _AP4_MVHD_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4NmhdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4NmhdAtom.cpp index 9a039b2d9..d6a660962 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4NmhdAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4NmhdAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - nmhd Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,35 +27,49 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4NmhdAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_NmhdAtom::AP4_NmhdAtom +| AP4_NmhdAtom::Create ++---------------------------------------------------------------------*/ +AP4_NmhdAtom* +AP4_NmhdAtom::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_NmhdAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_NmhdAtom::AP4_NmhdAtom +---------------------------------------------------------------------*/ AP4_NmhdAtom::AP4_NmhdAtom() : - AP4_Atom(AP4_ATOM_TYPE_NMHD, AP4_FULL_ATOM_HEADER_SIZE, true) + AP4_Atom(AP4_ATOM_TYPE_NMHD, AP4_FULL_ATOM_HEADER_SIZE, 0, 0) { } /*---------------------------------------------------------------------- -| AP4_NmhdAtom::AP4_NmhdAtom +| AP4_NmhdAtom::AP4_NmhdAtom +---------------------------------------------------------------------*/ -AP4_NmhdAtom::AP4_NmhdAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_NMHD, size, true, stream) +AP4_NmhdAtom::AP4_NmhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& /* stream */) : + AP4_Atom(AP4_ATOM_TYPE_NMHD, size, version, flags) { } /*---------------------------------------------------------------------- -| AP4_NmhdAtom::WriteFields +| AP4_NmhdAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result -AP4_NmhdAtom::WriteFields(AP4_ByteStream& stream) +AP4_NmhdAtom::WriteFields(AP4_ByteStream& /* stream */) { - // not implemented yet return AP4_SUCCESS; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4NmhdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4NmhdAtom.h index b7ad7d3ce..8c2efd336 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4NmhdAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4NmhdAtom.h @@ -2,7 +2,7 @@ | | AP4 - nmhd Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,22 +30,29 @@ #define _AP4_NMHD_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_NmhdAtom +| AP4_NmhdAtom +---------------------------------------------------------------------*/ class AP4_NmhdAtom : public AP4_Atom { public: + // class methods + static AP4_NmhdAtom* Create(AP4_Size size, AP4_ByteStream& stream); + // methods AP4_NmhdAtom(); - AP4_NmhdAtom(AP4_Size size, AP4_ByteStream& stream); virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // methods + AP4_NmhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); }; #endif // _AP4_NMHD_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ObjectDescriptor.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ObjectDescriptor.cpp new file mode 100644 index 000000000..1b74261d9 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ObjectDescriptor.cpp @@ -0,0 +1,430 @@ +/***************************************************************** +| +| AP4 - Object Descriptor +| +| 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 "Ap4ObjectDescriptor.h" +#include "Ap4DescriptorFactory.h" +#include "Ap4Utils.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_ObjectDescriptor) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_DescriptorUpdateCommand) + +/*---------------------------------------------------------------------- +| AP4_ObjectDescriptor::AP4_ObjectDescriptor ++---------------------------------------------------------------------*/ +AP4_ObjectDescriptor::AP4_ObjectDescriptor(AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_Descriptor(tag, header_size, payload_size), + m_UrlFlag(false) +{ +} + +/*---------------------------------------------------------------------- +| AP4_ObjectDescriptor::AP4_ObjectDescriptor ++---------------------------------------------------------------------*/ +AP4_ObjectDescriptor::AP4_ObjectDescriptor(AP4_UI08 tag, AP4_UI16 id) : + AP4_Descriptor(tag, 3, 2), + m_ObjectDescriptorId(id), + m_UrlFlag(false) +{ +} + +/*---------------------------------------------------------------------- +| AP4_ObjectDescriptor::AP4_ObjectDescriptor ++---------------------------------------------------------------------*/ +AP4_ObjectDescriptor::AP4_ObjectDescriptor(AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_Descriptor(tag, header_size, payload_size) +{ + AP4_Position start; + stream.Tell(start); + + // read descriptor fields + unsigned short bits; + stream.ReadUI16(bits); + m_ObjectDescriptorId = (bits>>6); + m_UrlFlag = ((bits&(1<<5))!=0); + + if (m_UrlFlag) { + unsigned char url_length; + stream.ReadUI08(url_length); + char url[256]; + stream.Read(url, url_length); + url[url_length] = '\0'; + m_Url = url; + } + + // read other descriptors + AP4_Position offset; + stream.Tell(offset); + AP4_SubStream* substream = new AP4_SubStream(stream, offset, + payload_size-AP4_Size(offset-start)); + AP4_Descriptor* descriptor = NULL; + while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream, + descriptor) + == AP4_SUCCESS) { + m_SubDescriptors.Add(descriptor); + } + substream->Release(); +} + +/*---------------------------------------------------------------------- +| AP4_ObjectDescriptor::~AP4_ObjectDescriptor ++---------------------------------------------------------------------*/ +AP4_ObjectDescriptor::~AP4_ObjectDescriptor() +{ + m_SubDescriptors.DeleteReferences(); +} + +/*---------------------------------------------------------------------- +| AP4_ObjectDescriptor::FindSubDescriptor ++---------------------------------------------------------------------*/ +AP4_Descriptor* +AP4_ObjectDescriptor::FindSubDescriptor(AP4_UI08 tag) const +{ + AP4_Descriptor* descriptor = NULL; + AP4_Result result = m_SubDescriptors.Find(AP4_DescriptorFinder(tag), descriptor); + if (AP4_FAILED(result)) return NULL; + + return descriptor; +} + +/*---------------------------------------------------------------------- +| AP4_ObjectDescriptor::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ObjectDescriptor::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // id and flag + unsigned short bits = (m_ObjectDescriptorId<<6)|(m_UrlFlag?(1<<5):0)|0x1F; + result = stream.WriteUI16(bits); + if (AP4_FAILED(result)) return result; + + // optional url + if (m_UrlFlag) { + stream.WriteUI08((AP4_UI08)m_Url.GetLength()); + stream.Write(m_Url.GetChars(), m_Url.GetLength()); + } + + // write the sub descriptors + m_SubDescriptors.Apply(AP4_DescriptorListWriter(stream)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ObjectDescriptor::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ObjectDescriptor::Inspect(AP4_AtomInspector& inspector) +{ + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(),m_PayloadSize); + inspector.StartElement("[ObjectDescriptor]", info); + inspector.AddField("id", m_ObjectDescriptorId); + if (m_UrlFlag) { + inspector.AddField("url", m_Url.GetChars()); + } + + // inspect children + m_SubDescriptors.Apply(AP4_DescriptorListInspector(inspector)); + + inspector.EndElement(); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_ObjectDescriptor::AddSubDescriptor ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ObjectDescriptor::AddSubDescriptor(AP4_Descriptor* descriptor) +{ + m_SubDescriptors.Add(descriptor); + m_PayloadSize += descriptor->GetSize(); + + // check that the header is still large enough to encode the payload + // length + unsigned int min_header_size = MinHeaderSize(m_PayloadSize); + if (min_header_size > m_HeaderSize) m_HeaderSize = min_header_size; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_InitialObjectDescriptor::AP4_InitialObjectDescriptor ++---------------------------------------------------------------------*/ +AP4_InitialObjectDescriptor::AP4_InitialObjectDescriptor( + AP4_UI08 tag, // should be AP4_DESCRIPTOR_TAG_IOD or AP4_DESCRIPTOR_TAG_MP4_IOD + AP4_UI16 object_descriptor_id, + bool include_inline_profile_level, + AP4_UI08 od_profile_level_indication, + AP4_UI08 scene_profile_level_indication, + AP4_UI08 audio_profile_level_indication, + AP4_UI08 visual_profile_level_indication, + AP4_UI08 graphics_profile_level_indication) : + AP4_ObjectDescriptor(tag, object_descriptor_id), + m_IncludeInlineProfileLevelFlag(include_inline_profile_level), + m_OdProfileLevelIndication(od_profile_level_indication), + m_SceneProfileLevelIndication(scene_profile_level_indication), + m_AudioProfileLevelIndication(audio_profile_level_indication), + m_VisualProfileLevelIndication(visual_profile_level_indication), + m_GraphicsProfileLevelIndication(graphics_profile_level_indication) +{ + m_PayloadSize = 7; +} + +/*---------------------------------------------------------------------- +| AP4_InitialObjectDescriptor::AP4_InitialObjectDescriptor ++---------------------------------------------------------------------*/ +AP4_InitialObjectDescriptor::AP4_InitialObjectDescriptor(AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_ObjectDescriptor(tag, header_size, payload_size), + m_OdProfileLevelIndication(0), + m_SceneProfileLevelIndication(0), + m_AudioProfileLevelIndication(0), + m_VisualProfileLevelIndication(0), + m_GraphicsProfileLevelIndication(0) +{ + AP4_Position start; + stream.Tell(start); + + // read descriptor fields + unsigned short bits; + stream.ReadUI16(bits); + m_ObjectDescriptorId = (bits>>6); + m_UrlFlag = ((bits&(1<<5))!=0); + m_IncludeInlineProfileLevelFlag = ((bits&(1<<4))!=0); + + if (m_UrlFlag) { + unsigned char url_length; + stream.ReadUI08(url_length); + char url[256]; + stream.Read(url, url_length); + url[url_length] = '\0'; + m_Url = url; + } else { + stream.ReadUI08(m_OdProfileLevelIndication); + stream.ReadUI08(m_SceneProfileLevelIndication); + stream.ReadUI08(m_AudioProfileLevelIndication); + stream.ReadUI08(m_VisualProfileLevelIndication); + stream.ReadUI08(m_GraphicsProfileLevelIndication); + } + + // read other descriptors + AP4_Position offset; + stream.Tell(offset); + AP4_SubStream* substream = new AP4_SubStream(stream, offset, + payload_size-AP4_Size(offset-start)); + AP4_Descriptor* descriptor = NULL; + while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream, + descriptor) + == AP4_SUCCESS) { + m_SubDescriptors.Add(descriptor); + } + substream->Release(); +} + +/*---------------------------------------------------------------------- +| AP4_InitialObjectDescriptor::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_InitialObjectDescriptor::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // id and flags + unsigned short bits = (m_ObjectDescriptorId<<6) | + (m_UrlFlag?(1<<5):0) | + (m_IncludeInlineProfileLevelFlag?(1<<4):0)| + 0xF; + result = stream.WriteUI16(bits); + if (AP4_FAILED(result)) return result; + + // optional url + if (m_UrlFlag) { + stream.WriteUI08((AP4_UI08)m_Url.GetLength()); + stream.Write(m_Url.GetChars(), m_Url.GetLength()); + } else { + stream.WriteUI08(m_OdProfileLevelIndication); + stream.WriteUI08(m_SceneProfileLevelIndication); + stream.WriteUI08(m_AudioProfileLevelIndication); + stream.WriteUI08(m_VisualProfileLevelIndication); + stream.WriteUI08(m_GraphicsProfileLevelIndication); + } + + // write the sub descriptors + m_SubDescriptors.Apply(AP4_DescriptorListWriter(stream)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_InitialObjectDescriptor::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_InitialObjectDescriptor::Inspect(AP4_AtomInspector& inspector) +{ + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(),m_PayloadSize); + inspector.StartElement("[InitialObjectDescriptor]", info); + inspector.AddField("id", m_ObjectDescriptorId); + if (m_UrlFlag) { + inspector.AddField("url", m_Url.GetChars()); + } else { + inspector.AddField("include inline profile level flag", + m_IncludeInlineProfileLevelFlag, + AP4_AtomInspector::HINT_BOOLEAN); + inspector.AddField("OD profile level", m_OdProfileLevelIndication, AP4_AtomInspector::HINT_HEX); + inspector.AddField("scene profile level", m_SceneProfileLevelIndication, AP4_AtomInspector::HINT_HEX); + inspector.AddField("audio profile level", m_AudioProfileLevelIndication, AP4_AtomInspector::HINT_HEX); + inspector.AddField("visual profile level", m_VisualProfileLevelIndication, AP4_AtomInspector::HINT_HEX); + inspector.AddField("graphics profile level", m_GraphicsProfileLevelIndication, AP4_AtomInspector::HINT_HEX); + } + + // inspect children + m_SubDescriptors.Apply(AP4_DescriptorListInspector(inspector)); + + inspector.EndElement(); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DescriptorUpdateCommand::AP4_DescriptorUpdateCommand ++---------------------------------------------------------------------*/ +AP4_DescriptorUpdateCommand::AP4_DescriptorUpdateCommand(AP4_UI08 tag) : + AP4_Command(tag, 2, 0) +{ +} + +/*---------------------------------------------------------------------- +| AP4_DescriptorUpdateCommand::AP4_DescriptorUpdateCommand ++---------------------------------------------------------------------*/ +AP4_DescriptorUpdateCommand::AP4_DescriptorUpdateCommand( + AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size) : + AP4_Command(tag, header_size, payload_size) +{ + // read the descriptors + AP4_Position offset; + stream.Tell(offset); + AP4_SubStream* substream = new AP4_SubStream(stream, offset, + payload_size); + AP4_Descriptor* descriptor = NULL; + while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream, descriptor) == AP4_SUCCESS) { + m_Descriptors.Add(descriptor); + } + substream->Release(); +} + +/*---------------------------------------------------------------------- +| AP4_DescriptorUpdateCommand::~AP4_DescriptorUpdateCommand ++---------------------------------------------------------------------*/ +AP4_DescriptorUpdateCommand::~AP4_DescriptorUpdateCommand() +{ + m_Descriptors.DeleteReferences(); +} + +/*---------------------------------------------------------------------- +| AP4_DescriptorUpdateCommand::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DescriptorUpdateCommand::WriteFields(AP4_ByteStream& stream) +{ + // write the descriptors + m_Descriptors.Apply(AP4_DescriptorListWriter(stream)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DescriptorUpdateCommand::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DescriptorUpdateCommand::Inspect(AP4_AtomInspector& inspector) +{ + char info[64]; + AP4_FormatString(info, sizeof(info), "size=%ld+%ld", + GetHeaderSize(),m_PayloadSize); + switch (GetTag()) { + case AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_UPDATE: + inspector.StartElement("[ObjectDescriptorUpdate]", info); + break; + + case AP4_COMMAND_TAG_IPMP_DESCRIPTOR_UPDATE: + inspector.StartElement("[IPMP_DescriptorUpdate]", info); + break; + + default: + inspector.StartElement("[DescriptorUpdate]", info); + break; + } + + // inspect children + m_Descriptors.Apply(AP4_DescriptorListInspector(inspector)); + + inspector.EndElement(); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DescriptorUpdateCommand::AddDescriptor ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DescriptorUpdateCommand::AddDescriptor(AP4_Descriptor* descriptor) +{ + m_Descriptors.Add(descriptor); + m_PayloadSize += descriptor->GetSize(); + + // check that the header is still large enough to encode the payload + // length + unsigned int min_header_size = MinHeaderSize(m_PayloadSize); + if (min_header_size > m_HeaderSize) m_HeaderSize = min_header_size; + + return AP4_SUCCESS; +} + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ObjectDescriptor.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ObjectDescriptor.h new file mode 100644 index 000000000..8b29c609c --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4ObjectDescriptor.h @@ -0,0 +1,167 @@ +/***************************************************************** +| +| AP4 - Object Descriptor +| +| 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_OBJECT_DESCRIPTOR_H_ +#define _AP4_OBJECT_DESCRIPTOR_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4List.h" +#include "Ap4String.h" +#include "Ap4Descriptor.h" +#include "Ap4Command.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI08 AP4_DESCRIPTOR_TAG_OD = 0x01; +const AP4_UI08 AP4_DESCRIPTOR_TAG_IOD = 0x02; +const AP4_UI08 AP4_DESCRIPTOR_TAG_MP4_OD = 0x11; +const AP4_UI08 AP4_DESCRIPTOR_TAG_MP4_IOD = 0x10; + +/*---------------------------------------------------------------------- +| AP4_ObjectDescriptor ++---------------------------------------------------------------------*/ +class AP4_ObjectDescriptor : public AP4_Descriptor +{ + public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_ObjectDescriptor, AP4_Descriptor) + + // methods + AP4_ObjectDescriptor(AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size); + AP4_ObjectDescriptor(AP4_UI08 tag, AP4_UI16 id); + virtual ~AP4_ObjectDescriptor(); + + /** + * Add a sub-descriptor. + * Ownership of the sub-descriptor object is transfered. + */ + virtual AP4_Result AddSubDescriptor(AP4_Descriptor* descriptor); + + virtual AP4_Descriptor* FindSubDescriptor(AP4_UI08 tag) const; + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + + // accessors + AP4_UI16 GetObjectDescriptorId() const { return m_ObjectDescriptorId; } + bool GetUrlFlag() const { return m_UrlFlag; } + const AP4_String& GetUrl() const { return m_Url;} + + protected: + // constructor + AP4_ObjectDescriptor(AP4_UI08 tag, AP4_Size header_size, AP4_Size payload_size); + + // members + AP4_UI16 m_ObjectDescriptorId; + bool m_UrlFlag; + AP4_String m_Url; + mutable AP4_List<AP4_Descriptor> m_SubDescriptors; +}; + +/*---------------------------------------------------------------------- +| AP4_InitialObjectDescriptor ++---------------------------------------------------------------------*/ +class AP4_InitialObjectDescriptor : public AP4_ObjectDescriptor +{ + public: + // methods + AP4_InitialObjectDescriptor(AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size); + AP4_InitialObjectDescriptor(AP4_UI08 tag, // should be AP4_DESCRIPTOR_TAG_IOD or AP4_DESCRIPTOR_TAG_MP4_IOD + AP4_UI16 object_descriptor_id, + bool include_inline_profile_level, + AP4_UI08 od_profile_level_indication, + AP4_UI08 scene_profile_level_indication, + AP4_UI08 audio_profile_level_indication, + AP4_UI08 visual_profile_level_indication, + AP4_UI08 graphics_profile_level_indication); + + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + + // accessors + bool GetIncludeProfileLevelFlag() const { return m_IncludeInlineProfileLevelFlag; } + AP4_UI08 GetOdProfileLevelIndication() const { return m_OdProfileLevelIndication; } + AP4_UI08 GetSceneProfileLevelIndication() const { return m_SceneProfileLevelIndication; } + AP4_UI08 GetAudioProfileLevelIndication() const { return m_AudioProfileLevelIndication; } + AP4_UI08 GetVisualProfileLevelIndication() const { return m_VisualProfileLevelIndication; } + AP4_UI08 GetGraphicsProfileLevelIndication() const { return m_GraphicsProfileLevelIndication; } + + private: + // members + bool m_IncludeInlineProfileLevelFlag; + AP4_UI08 m_OdProfileLevelIndication; + AP4_UI08 m_SceneProfileLevelIndication; + AP4_UI08 m_AudioProfileLevelIndication; + AP4_UI08 m_VisualProfileLevelIndication; + AP4_UI08 m_GraphicsProfileLevelIndication; +}; + +/*---------------------------------------------------------------------- +| AP4_DescriptorUpdateCommand ++---------------------------------------------------------------------*/ +/** + * This class is used for ObjectDescriptorUpdateCommand and + * IPMP_DescriptorUpdateCommand + */ +class AP4_DescriptorUpdateCommand : public AP4_Command +{ + public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_DescriptorUpdateCommand, AP4_Command) + + // methods + AP4_DescriptorUpdateCommand(AP4_UI08 tag); + AP4_DescriptorUpdateCommand(AP4_ByteStream& stream, + AP4_UI08 tag, + AP4_Size header_size, + AP4_Size payload_size); + virtual ~AP4_DescriptorUpdateCommand(); + virtual AP4_Result AddDescriptor(AP4_Descriptor* descriptor); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + + // accessors + const AP4_List<AP4_Descriptor>& GetDescriptors() { return m_Descriptors; } + + protected: + // members + mutable AP4_List<AP4_Descriptor> m_Descriptors; +}; + +#endif // _AP4_OBJECT_DESCRIPTOR_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdafAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdafAtom.cpp new file mode 100644 index 000000000..28805ecef --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdafAtom.cpp @@ -0,0 +1,116 @@ +/***************************************************************** +| +| AP4 - odaf 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 "Ap4Utils.h" +#include "Ap4OdafAtom.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_OdafAtom) + +/*---------------------------------------------------------------------- +| AP4_OdafAtom::Create ++---------------------------------------------------------------------*/ +AP4_OdafAtom* +AP4_OdafAtom::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_OdafAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_OdafAtom::AP4_OdafAtom ++---------------------------------------------------------------------*/ +AP4_OdafAtom::AP4_OdafAtom(bool selective_encryption, + AP4_UI08 key_length_indicator, + AP4_UI08 iv_length) : + AP4_Atom(AP4_ATOM_TYPE_ODAF, AP4_FULL_ATOM_HEADER_SIZE+3, 0, 0), + m_SelectiveEncryption(selective_encryption), + m_KeyIndicatorLength(key_length_indicator), + m_IvLength(iv_length) +{ +} + +/*---------------------------------------------------------------------- +| AP4_OdafAtom::AP4_OdafAtom ++---------------------------------------------------------------------*/ +AP4_OdafAtom::AP4_OdafAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_ODAF, size, version, flags) +{ + AP4_UI08 s; + stream.ReadUI08(s); + m_SelectiveEncryption = ((s&0x80) != 0); + stream.ReadUI08(m_KeyIndicatorLength); + stream.ReadUI08(m_IvLength); +} + +/*---------------------------------------------------------------------- +| AP4_OdafAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OdafAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // selective encryption + result = stream.WriteUI08(m_SelectiveEncryption ? 0x80 : 0); + if (AP4_FAILED(result)) return result; + + // key indicator length + result = stream.WriteUI08(m_KeyIndicatorLength); + if (AP4_FAILED(result)) return result; + + // IV length + result = stream.WriteUI08(m_IvLength); + if (AP4_FAILED(result)) return result; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OdafAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OdafAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("selective_encryption", m_SelectiveEncryption); + inspector.AddField("key_indicator_length", m_KeyIndicatorLength); + inspector.AddField("IV_length", m_IvLength); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdafAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdafAtom.h new file mode 100644 index 000000000..22ba860ee --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdafAtom.h @@ -0,0 +1,74 @@ +/***************************************************************** +| +| AP4 - odaf Atom +| +| 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_ODAF_ATOM_H_ +#define _AP4_ODAF_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_OdafAtom ++---------------------------------------------------------------------*/ +class AP4_OdafAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_OdafAtom, AP4_Atom) + + // class methods + static AP4_OdafAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_OdafAtom(bool m_SelectiveEncryption, + AP4_UI08 m_KeyIndicatorLength, + AP4_UI08 m_IvLength); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // accessors + bool GetSelectiveEncryption() { return m_SelectiveEncryption; } + AP4_UI08 GetKeyIndicatorLength() { return m_KeyIndicatorLength; } + AP4_UI08 GetIvLength() { return m_IvLength; } + +private: + // methods + AP4_OdafAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + bool m_SelectiveEncryption; + AP4_UI08 m_KeyIndicatorLength; + AP4_UI08 m_IvLength; +}; + +#endif // _AP4_ODAF_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OddaAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OddaAtom.cpp new file mode 100644 index 000000000..d7a08796a --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OddaAtom.cpp @@ -0,0 +1,170 @@ +/***************************************************************** +| +| AP4 - odda 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 "Ap4Utils.h" +#include "Ap4OddaAtom.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_OddaAtom) + +/*---------------------------------------------------------------------- +| AP4_OddaAtom::Create ++---------------------------------------------------------------------*/ +AP4_OddaAtom* +AP4_OddaAtom::Create(AP4_UI64 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_OddaAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_OddaAtom::AP4_OddaAtom ++---------------------------------------------------------------------*/ +AP4_OddaAtom::AP4_OddaAtom(AP4_UI64 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_ODDA, size, true, version, flags) +{ + // data length + stream.ReadUI64(m_EncryptedDataLength); + + // get the source stream position + AP4_Position position; + stream.Tell(position); + + // create a substream to represent the payload + m_EncryptedPayload = new AP4_SubStream(stream, position, m_EncryptedDataLength); + + // seek to the end + stream.Seek(position+m_EncryptedDataLength); +} + +/*---------------------------------------------------------------------- +| AP4_OddaAtom::AP4_OddaAtom ++---------------------------------------------------------------------*/ +AP4_OddaAtom::AP4_OddaAtom(AP4_ByteStream& encrypted_payload) : + AP4_Atom(AP4_ATOM_TYPE_ODDA, 0, true, 0, 0) +{ + // encrypted data length + encrypted_payload.GetSize(m_EncryptedDataLength); + + // update our size + SetSize(AP4_FULL_ATOM_HEADER_SIZE_64+8+m_EncryptedDataLength, true); + + // keep a reference to the encrypted payload + m_EncryptedPayload = &encrypted_payload; + m_EncryptedPayload->AddReference(); +} + +/*---------------------------------------------------------------------- +| AP4_OddaAtom::~AP4_OddaAtom ++---------------------------------------------------------------------*/ +AP4_OddaAtom::~AP4_OddaAtom() +{ + if (m_EncryptedPayload) m_EncryptedPayload->Release(); +} + + +/*---------------------------------------------------------------------- +| AP4_OddaAtom::SetEncryptedPayload ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OddaAtom::SetEncryptedPayload(AP4_ByteStream& stream, AP4_LargeSize length) +{ + // keep a reference to the stream + if (m_EncryptedPayload) { + m_EncryptedPayload->Release(); + } + m_EncryptedPayload = &stream; + m_EncryptedPayload->AddReference(); + + // update the size + m_EncryptedDataLength = length; + SetSize(AP4_FULL_ATOM_HEADER_SIZE_64 + 8 + length, true); + if (m_Parent) m_Parent->OnChildChanged(this); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OddaAtom::SetEncryptedPayload ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OddaAtom::SetEncryptedPayload(AP4_ByteStream& stream) +{ + // the new encrypted data length is the size of the stream + AP4_LargeSize length; + AP4_Result result = stream.GetSize(length); + if (AP4_FAILED(result)) return result; + + return SetEncryptedPayload(stream, length); +} + +/*---------------------------------------------------------------------- +| AP4_OddaAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OddaAtom::WriteFields(AP4_ByteStream& stream) +{ + // write the content type + AP4_CHECK(stream.WriteUI64(m_EncryptedDataLength)); + + // check that we have a source stream + // and a normal size + if (m_EncryptedPayload == NULL || GetSize() < 8) { + return AP4_FAILURE; + } + + // rewind the encrypted stream + AP4_CHECK(m_EncryptedPayload->Seek(0)); + + // copy the encrypted stream to the output + AP4_CHECK(m_EncryptedPayload->CopyTo(stream, m_EncryptedDataLength)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OddaAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OddaAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("encrypted_data_length", (AP4_UI32)m_EncryptedDataLength); + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OddaAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OddaAtom.h new file mode 100644 index 000000000..58a402ce5 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OddaAtom.h @@ -0,0 +1,87 @@ +/***************************************************************** +| +| AP4 - odda Atom +| +| 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_ODDA_ATOM_H_ +#define _AP4_ODDA_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" +#include "Ap4String.h" + +/*---------------------------------------------------------------------- +| AP4_OddaAtom ++---------------------------------------------------------------------*/ +class AP4_OddaAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_OddaAtom, AP4_Atom) + + // class methods + static AP4_OddaAtom* Create(AP4_UI64 size, + AP4_ByteStream& stream); + + // constructor + AP4_OddaAtom(AP4_ByteStream& encrypted_payload); + + // destructor + ~AP4_OddaAtom(); + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // accessors + AP4_UI64 GetEncryptedDataLength() { return m_EncryptedDataLength; } + + /** + * Sets the encrypted payload stream (and releases any existing stream references) + */ + AP4_Result SetEncryptedPayload(AP4_ByteStream& stream); + AP4_Result SetEncryptedPayload(AP4_ByteStream& stream, AP4_LargeSize length); + + /** + * Returns a reference to the encrypted payload stream (does not increment the reference counter) + */ + AP4_ByteStream& GetEncryptedPayload() { return *m_EncryptedPayload; } + +private: + // methods + AP4_OddaAtom(AP4_UI64 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI64 m_EncryptedDataLength; + AP4_ByteStream* m_EncryptedPayload; +}; + +#endif // _AP4_ODDA_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdheAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdheAtom.cpp new file mode 100644 index 000000000..f4e2bf5c8 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdheAtom.cpp @@ -0,0 +1,130 @@ +/***************************************************************** +| +| AP4 - odhe 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 "Ap4Utils.h" +#include "Ap4OdheAtom.h" +#include "Ap4OhdrAtom.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_OdheAtom) + +/*---------------------------------------------------------------------- +| AP4_OdheAtom::Create ++---------------------------------------------------------------------*/ +AP4_OdheAtom* +AP4_OdheAtom::Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) +{ + 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_OdheAtom(size, version, flags, stream, atom_factory); +} + +/*---------------------------------------------------------------------- +| AP4_OdheAtom::AP4_OdheAtom ++---------------------------------------------------------------------*/ +AP4_OdheAtom::AP4_OdheAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_ContainerAtom(AP4_ATOM_TYPE_ODHE, size, false, version, flags) +{ + // read the content type + AP4_UI08 content_type_length; + stream.ReadUI08(content_type_length); + char content_type[256]; + stream.Read(content_type, content_type_length); + m_ContentType.Assign(content_type, content_type_length); + + // read the children + AP4_Size bytes_available = size-(AP4_FULL_ATOM_HEADER_SIZE+1+content_type_length); + ReadChildren(atom_factory, stream, bytes_available); +} + +/*---------------------------------------------------------------------- +| AP4_OdheAtom::AP4_OdheAtom ++---------------------------------------------------------------------*/ +AP4_OdheAtom::AP4_OdheAtom(const char* content_type, + AP4_OhdrAtom* ohdr) : + AP4_ContainerAtom(AP4_ATOM_TYPE_ODHE, (AP4_UI32)0, (AP4_UI32)0), + m_ContentType(content_type) +{ + m_Size32 += 1+m_ContentType.GetLength(); + AddChild(ohdr); +} + +/*---------------------------------------------------------------------- +| AP4_OdheAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OdheAtom::WriteFields(AP4_ByteStream& stream) +{ + // write the content type + AP4_CHECK(stream.WriteUI08((AP4_UI08)m_ContentType.GetLength())); + if (m_ContentType.GetLength()) { + AP4_CHECK(stream.Write(m_ContentType.GetChars(), m_ContentType.GetLength())); + } + + // write the children + return m_Children.Apply(AP4_AtomListWriter(stream)); +} + +/*---------------------------------------------------------------------- +| AP4_OdheAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OdheAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("content_type", m_ContentType.GetChars()); + return InspectChildren(inspector); +} + +/*---------------------------------------------------------------------- +| AP4_OdheAtom::OnChildChanged ++---------------------------------------------------------------------*/ +void +AP4_OdheAtom::OnChildChanged(AP4_Atom*) +{ + // remcompute our size + AP4_UI64 size = GetHeaderSize()+1+m_ContentType.GetLength(); + m_Children.Apply(AP4_AtomSizeAdder(size)); + SetSize(size); + + // update our parent + if (m_Parent) m_Parent->OnChildChanged(this); +} + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdheAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdheAtom.h new file mode 100644 index 000000000..44477ae13 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OdheAtom.h @@ -0,0 +1,87 @@ +/***************************************************************** +| +| AP4 - odhe Atom +| +| 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_ODHE_ATOM_H_ +#define _AP4_ODHE_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" +#include "Ap4ContainerAtom.h" +#include "Ap4String.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_OhdrAtom; + +/*---------------------------------------------------------------------- +| AP4_OdheAtom ++---------------------------------------------------------------------*/ +class AP4_OdheAtom : public AP4_ContainerAtom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_OdheAtom, AP4_ContainerAtom) + + // class methods + static AP4_OdheAtom* Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // constructor + /** + * @param: ohdr ohdr atom passed with transfer of ownership semantics + */ + AP4_OdheAtom(const char* content_type, AP4_OhdrAtom* ohdr); + + // AP4_Atom methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // AP4_AtomParent methods + virtual void OnChildChanged(AP4_Atom* child); + + // methods + const AP4_String& GetContentType() { return m_ContentType; } + +private: + // methods + AP4_OdheAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // members + AP4_String m_ContentType; + +}; + +#endif // _AP4_ODHE_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OhdrAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OhdrAtom.cpp new file mode 100644 index 000000000..f74e0d8f5 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OhdrAtom.cpp @@ -0,0 +1,214 @@ +/***************************************************************** +| +| AP4 - ohdr 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 "Ap4Utils.h" +#include "Ap4OhdrAtom.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_OhdrAtom) + +/*---------------------------------------------------------------------- +| AP4_OhdrAtom::Create ++---------------------------------------------------------------------*/ +AP4_OhdrAtom* +AP4_OhdrAtom::Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) +{ + 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_OhdrAtom(size, version, flags, stream, atom_factory); +} + +/*---------------------------------------------------------------------- +| AP4_OhdrAtom::AP4_OhdrAtom ++---------------------------------------------------------------------*/ +AP4_OhdrAtom::AP4_OhdrAtom(AP4_UI08 encryption_method, + AP4_UI08 padding_scheme, + AP4_UI64 plaintext_length, + const char* content_id, + const char* rights_issuer_url, + const AP4_Byte* textual_headers, + AP4_Size textual_headers_size) : + AP4_ContainerAtom(AP4_ATOM_TYPE_OHDR, (AP4_UI32)0, (AP4_UI32)0), + m_EncryptionMethod(encryption_method), + m_PaddingScheme(padding_scheme), + m_PlaintextLength(plaintext_length), + m_ContentId(content_id), + m_RightsIssuerUrl(rights_issuer_url), + m_TextualHeaders(textual_headers, textual_headers_size) +{ + m_Size32 += 1+1+8+2+2+2+m_ContentId.GetLength()+m_RightsIssuerUrl.GetLength()+textual_headers_size; +} + +/*---------------------------------------------------------------------- +| AP4_OhdrAtom::AP4_OhdrAtom ++---------------------------------------------------------------------*/ +AP4_OhdrAtom::AP4_OhdrAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_ContainerAtom(AP4_ATOM_TYPE_OHDR, size, false, version, flags) +{ + // encryption method + stream.ReadUI08(m_EncryptionMethod); + + // padding scheme + stream.ReadUI08(m_PaddingScheme); + + // plaintext length + stream.ReadUI64(m_PlaintextLength); + + // string lengths + AP4_UI16 content_id_length; + AP4_UI16 rights_issuer_url_length; + AP4_UI16 textual_headers_length; + stream.ReadUI16(content_id_length); + stream.ReadUI16(rights_issuer_url_length); + stream.ReadUI16(textual_headers_length); + + // content id + char* buffer = new char[content_id_length]; + stream.Read(buffer, content_id_length); + m_ContentId.Assign(buffer, content_id_length); + delete[] buffer; + + // rights issuer url + buffer = new char[rights_issuer_url_length]; + stream.Read(buffer, rights_issuer_url_length); + m_RightsIssuerUrl.Assign(buffer, rights_issuer_url_length); + delete[] buffer; + + // textual headers + buffer = new char[textual_headers_length]; + stream.Read(buffer, textual_headers_length); + m_TextualHeaders.SetData((AP4_Byte*)buffer, textual_headers_length); + delete[] buffer; + + // read the children + AP4_Size bytes_used = AP4_FULL_ATOM_HEADER_SIZE+1+1+8+2+2+2+content_id_length+rights_issuer_url_length+textual_headers_length; + if (bytes_used <= size) { + ReadChildren(atom_factory, stream, size-bytes_used); + } +} + +/*---------------------------------------------------------------------- +| AP4_OhdrAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OhdrAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_CHECK(stream.WriteUI08(m_EncryptionMethod)); + AP4_CHECK(stream.WriteUI08(m_PaddingScheme)); + AP4_CHECK(stream.WriteUI64(m_PlaintextLength)); + AP4_CHECK(stream.WriteUI16((AP4_UI16)m_ContentId.GetLength())); + AP4_CHECK(stream.WriteUI16((AP4_UI16)m_RightsIssuerUrl.GetLength())); + AP4_CHECK(stream.WriteUI16((AP4_UI16)m_TextualHeaders.GetDataSize())); + AP4_CHECK(stream.Write(m_ContentId.GetChars(), m_ContentId.GetLength())); + AP4_CHECK(stream.Write(m_RightsIssuerUrl.GetChars(), m_RightsIssuerUrl.GetLength())); + AP4_CHECK(stream.Write(m_TextualHeaders.GetData(), m_TextualHeaders.GetDataSize())); + + // write the children + return m_Children.Apply(AP4_AtomListWriter(stream)); +} + +/*---------------------------------------------------------------------- +| AP4_OhdrAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OhdrAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("encryption_method", m_EncryptionMethod); + inspector.AddField("padding_scheme", m_PaddingScheme); + inspector.AddField("plaintext_length", (AP4_UI32)m_PlaintextLength); + inspector.AddField("content_id", m_ContentId.GetChars()); + inspector.AddField("rights_issuer_url", m_RightsIssuerUrl.GetChars()); + + { + AP4_DataBuffer output_buffer; + AP4_Result result; + + result = output_buffer.Reserve(1+m_TextualHeaders.GetDataSize()); + if (AP4_FAILED(result)) { + inspector.AddField("textual_headers", + m_TextualHeaders.UseData(), + m_TextualHeaders.GetDataSize(), + AP4_AtomInspector::HINT_HEX); + } else { + AP4_Size data_len = m_TextualHeaders.GetDataSize(); + AP4_Byte* textual_headers_string; + AP4_Byte* curr; + + output_buffer.SetData((const AP4_Byte*)m_TextualHeaders.GetData(), m_TextualHeaders.GetDataSize()); + curr = textual_headers_string = output_buffer.UseData(); + textual_headers_string[m_TextualHeaders.GetDataSize()] = '\0'; + while(curr < textual_headers_string+data_len) { + if ('\0' == *curr) { + *curr = '\n'; + } + curr++; + } + inspector.AddField("textual_headers", (const char*) textual_headers_string); + } + } + + return InspectChildren(inspector); +} + +/*---------------------------------------------------------------------- +| AP4_OhdrAtom::Clone ++---------------------------------------------------------------------*/ +AP4_Atom* +AP4_OhdrAtom::Clone() +{ + AP4_OhdrAtom* clone; + clone = new AP4_OhdrAtom(m_EncryptionMethod, + m_PaddingScheme, + m_PlaintextLength, + m_ContentId.GetChars(), + m_RightsIssuerUrl.GetChars(), + m_TextualHeaders.GetData(), + m_TextualHeaders.GetDataSize()); + + AP4_List<AP4_Atom>::Item* child_item = m_Children.FirstItem(); + while (child_item) { + AP4_Atom* child_clone = child_item->GetData()->Clone(); + if (child_clone) clone->AddChild(child_clone); + child_item = child_item->GetNext(); + } + + return clone; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OhdrAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OhdrAtom.h new file mode 100644 index 000000000..afee7f5fb --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OhdrAtom.h @@ -0,0 +1,104 @@ +/***************************************************************** +| +| AP4 - ohdr Atom +| +| 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_OHDR_ATOM_H_ +#define _AP4_OHDR_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" +#include "Ap4ContainerAtom.h" +#include "Ap4String.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI08 AP4_OMA_DCF_ENCRYPTION_METHOD_NULL = 0; +const AP4_UI08 AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CBC = 1; +const AP4_UI08 AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CTR = 2; + +const AP4_UI08 AP4_OMA_DCF_PADDING_SCHEME_NONE = 0; +const AP4_UI08 AP4_OMA_DCF_PADDING_SCHEME_RFC_2630 = 1; + +/*---------------------------------------------------------------------- +| AP4_OhdrAtom ++---------------------------------------------------------------------*/ +class AP4_OhdrAtom : public AP4_ContainerAtom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_OhdrAtom, AP4_ContainerAtom) + + // class methods + static AP4_OhdrAtom* Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // constructor + AP4_OhdrAtom(AP4_UI08 encryption_method, + AP4_UI08 padding_scheme, + AP4_UI64 plaintext_length, + const char* content_id, + const char* rights_issuer_url, + const AP4_Byte* textual_headers, + AP4_Size textual_headers_size); + + // methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Atom* Clone(); + + // accessors + AP4_UI08 GetEncryptionMethod() const { return m_EncryptionMethod; } + void SetEncryptionMethod(AP4_UI08 encryption_method) { m_EncryptionMethod = encryption_method; } + AP4_UI08 GetPaddingScheme() const { return m_PaddingScheme; } + void SetPaddingScheme(AP4_UI08 padding_scheme) { m_PaddingScheme = padding_scheme; } + AP4_UI64 GetPlaintextLength() const { return m_PlaintextLength; } + const AP4_String& GetContentId() const { return m_ContentId; } + const AP4_String& GetRightsIssuerUrl() const { return m_RightsIssuerUrl; } + const AP4_DataBuffer& GetTextualHeaders() const { return m_TextualHeaders; } + +private: + // methods + AP4_OhdrAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // members + AP4_UI08 m_EncryptionMethod; + AP4_UI08 m_PaddingScheme; + AP4_UI64 m_PlaintextLength; + AP4_String m_ContentId; + AP4_String m_RightsIssuerUrl; + AP4_DataBuffer m_TextualHeaders; +}; + +#endif // _AP4_OHDR_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OmaDcf.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OmaDcf.cpp new file mode 100644 index 000000000..c5eeb3c1e --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OmaDcf.cpp @@ -0,0 +1,1111 @@ +/***************************************************************** +| +| AP4 - OMA DCF 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 "Ap4SchmAtom.h" +#include "Ap4StsdAtom.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 "Ap4OdafAtom.h" +#include "Ap4OmaDcf.h" +#include "Ap4OhdrAtom.h" +#include "Ap4OddaAtom.h" +#include "Ap4OdheAtom.h" +#include "Ap4FtypAtom.h" +#include "Ap4GrpiAtom.h" + +/*---------------------------------------------------------------------- +| AP4_OmaDcfAtomDecrypter::DecryptAtoms ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfAtomDecrypter::DecryptAtoms(AP4_AtomParent& atoms, + AP4_Processor::ProgressListener* /*listener*/, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ProtectionKeyMap& key_map) +{ + unsigned int index = 1; + for (AP4_List<AP4_Atom>::Item* item = atoms.GetChildren().FirstItem(); + item; + item = item->GetNext()) { + AP4_Atom* atom = item->GetData(); + if (atom->GetType() != AP4_ATOM_TYPE_ODRM) continue; + + // check that we have the key + const AP4_UI08* key = key_map.GetKey(index++); + if (key == NULL) return AP4_ERROR_INVALID_PARAMETERS; + + // check that we have all the atoms we need + AP4_ContainerAtom* odrm = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom); + if (odrm == NULL) continue; // not enough info + AP4_OdheAtom* odhe = AP4_DYNAMIC_CAST(AP4_OdheAtom, odrm->GetChild(AP4_ATOM_TYPE_ODHE)); + if (odhe == NULL) continue; // not enough info + AP4_OddaAtom* odda = AP4_DYNAMIC_CAST(AP4_OddaAtom, odrm->GetChild(AP4_ATOM_TYPE_ODDA));; + if (odda == NULL) continue; // not enough info + AP4_OhdrAtom* ohdr = AP4_DYNAMIC_CAST(AP4_OhdrAtom, odhe->GetChild(AP4_ATOM_TYPE_OHDR)); + if (ohdr == NULL) continue; // not enough info + + // do nothing if the atom is not encrypted + if (ohdr->GetEncryptionMethod() == AP4_OMA_DCF_ENCRYPTION_METHOD_NULL) { + continue; + } + + // create the byte stream + AP4_ByteStream* cipher_stream = NULL; + AP4_Result result = CreateDecryptingStream(*odrm, + key, + 16, + block_cipher_factory, + cipher_stream); + if (AP4_SUCCEEDED(result)) { + // replace the odda atom's payload with the decrypted stream + odda->SetEncryptedPayload(*cipher_stream, ohdr->GetPlaintextLength()); + cipher_stream->Release(); + + // the atom will now be in the clear + ohdr->SetEncryptionMethod(AP4_OMA_DCF_ENCRYPTION_METHOD_NULL); + ohdr->SetPaddingScheme(AP4_OMA_DCF_PADDING_SCHEME_NONE); + } + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfAtomDecrypter::CreateDecryptingStream ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfAtomDecrypter::CreateDecryptingStream( + AP4_ContainerAtom& odrm, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ByteStream*& stream) +{ + // default return values + stream = NULL; + + AP4_OdheAtom* odhe = AP4_DYNAMIC_CAST(AP4_OdheAtom, odrm.GetChild(AP4_ATOM_TYPE_ODHE)); + if (odhe == NULL) return AP4_ERROR_INVALID_FORMAT; + AP4_OddaAtom* odda = AP4_DYNAMIC_CAST(AP4_OddaAtom, odrm.GetChild(AP4_ATOM_TYPE_ODDA));; + if (odda == NULL) return AP4_ERROR_INVALID_FORMAT; + AP4_OhdrAtom* ohdr = AP4_DYNAMIC_CAST(AP4_OhdrAtom, odhe->GetChild(AP4_ATOM_TYPE_OHDR)); + if (ohdr == NULL) return AP4_ERROR_INVALID_FORMAT; + + // shortcut for non-encrypted files + if (ohdr->GetEncryptionMethod() == AP4_OMA_DCF_ENCRYPTION_METHOD_NULL) { + stream = &odda->GetEncryptedPayload(); + stream->AddReference(); + return AP4_SUCCESS; + } + + // if this is part of a group, use the group key to obtain the content + // key (note that the field called GroupKey in the spec is actually not + // the group key but the content key encrypted with the group key... + AP4_GrpiAtom* grpi = AP4_DYNAMIC_CAST(AP4_GrpiAtom, ohdr->GetChild(AP4_ATOM_TYPE_GRPI)); + AP4_UI08* key_buffer = NULL; + if (grpi) { + // sanity check on the encrypted key size + if (grpi->GetGroupKey().GetDataSize() < 32) { + return AP4_ERROR_INVALID_FORMAT; + } + + // create a block cipher to decrypt the content key + AP4_BlockCipher* block_cipher = NULL; + AP4_Result result; + + // create a stream cipher from the block cipher + AP4_StreamCipher* stream_cipher = NULL; + switch (ohdr->GetEncryptionMethod()) { + case AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CBC: + result = block_cipher_factory->Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::DECRYPT, + key, + key_size, + block_cipher); + if (AP4_FAILED(result)) return result; + stream_cipher = new AP4_CbcStreamCipher(block_cipher, AP4_CbcStreamCipher::DECRYPT); + break; + + case AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CTR: + result = block_cipher_factory->Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::ENCRYPT, + key, + key_size, + block_cipher); + if (AP4_FAILED(result)) return result; + stream_cipher = new AP4_CtrStreamCipher(block_cipher, NULL, 16); + break; + + default: + return AP4_ERROR_NOT_SUPPORTED; + } + + // set the IV + stream_cipher->SetIV(grpi->GetGroupKey().GetData()); + + // decrypt the content key + AP4_Size key_buffer_size = grpi->GetGroupKey().GetDataSize(); // worst case + key_buffer = new AP4_UI08[key_buffer_size]; + result = stream_cipher->ProcessBuffer(grpi->GetGroupKey().GetData()+16, + grpi->GetGroupKey().GetDataSize()-16, + key_buffer, + &key_buffer_size, + true); + delete stream_cipher; // this will also delete the block cipher + if (AP4_FAILED(result)) { + delete[] key_buffer; + return result; + } + + // point to the new key value + key = key_buffer; + key_size = key_buffer_size; + } + + AP4_OmaDcfCipherMode mode; + switch (ohdr->GetEncryptionMethod()) { + case AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CBC: + mode = AP4_OMA_DCF_CIPHER_MODE_CBC; + break; + case AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CTR: + mode = AP4_OMA_DCF_CIPHER_MODE_CTR; + break; + default: + return AP4_ERROR_NOT_SUPPORTED; + } + + AP4_Result result; + result = CreateDecryptingStream(mode, + odda->GetEncryptedPayload(), + ohdr->GetPlaintextLength(), + key, key_size, + block_cipher_factory, + stream); + + // cleanup + delete[] key_buffer; + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfAtomDecrypter::CreateDecryptingStream ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfAtomDecrypter::CreateDecryptingStream( + AP4_OmaDcfCipherMode mode, + AP4_ByteStream& encrypted_stream, + AP4_LargeSize cleartext_size, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ByteStream*& stream) +{ + // default return value + stream = NULL; + + // get the encrypted size (includes IV and padding) + AP4_LargeSize encrypted_size = 0; + AP4_Result result = encrypted_stream.GetSize(encrypted_size); + if (AP4_FAILED(result)) return result; + + // check that the encrypted size is consistent with the cipher mode + AP4_DecryptingStream::CipherMode cipher_mode; + if (mode == AP4_OMA_DCF_CIPHER_MODE_CBC) { + // we need at least 16 bytes of IV and 32 bytes of data+padding + // we also need a multiple of the block size + if (encrypted_size < 48 || ((encrypted_size % 16) != 0)) { + return AP4_ERROR_INVALID_FORMAT; + } + cipher_mode = AP4_DecryptingStream::CIPHER_MODE_CBC; + } else if (mode == AP4_OMA_DCF_CIPHER_MODE_CTR) { + // we need at least 16 bytes of IV + if (encrypted_size < 16) { + return AP4_ERROR_INVALID_FORMAT; + } + cipher_mode = AP4_DecryptingStream::CIPHER_MODE_CTR; + } else { + return AP4_ERROR_NOT_SUPPORTED; + } + + // read the IV + AP4_UI08 iv[16]; + result = encrypted_stream.Seek(0); + if (AP4_FAILED(result)) return result; + result = encrypted_stream.Read(iv, 16); + if (AP4_FAILED(result)) return result; + + // create a sub stream with just the encrypted payload without the IV + AP4_ByteStream* sub_stream = new AP4_SubStream(encrypted_stream, 16, encrypted_size-16); + + // create the decrypting cipher + result = AP4_DecryptingStream::Create(cipher_mode, + *sub_stream, + cleartext_size, + iv, + 16, + key, + key_size, + block_cipher_factory, + stream); + + // we don't keep our own reference to the sub stream + sub_stream->Release(); + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfSampleDecrypter::Create ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfSampleDecrypter::Create(AP4_ProtectedSampleDescription* sample_description, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_OmaDcfSampleDecrypter*& cipher) +{ + // check the parameters + if (key == NULL || block_cipher_factory == NULL) { + return AP4_ERROR_INVALID_PARAMETERS; + } + + // default return value + cipher = NULL; + + // get the scheme info atom + AP4_ContainerAtom* schi = sample_description->GetSchemeInfo()->GetSchiAtom(); + if (schi == NULL) return AP4_ERROR_INVALID_FORMAT; + + // get and check the cipher params + // NOTE: we only support an IV Length less than or equal to the cipher block size, + // and we don't know how to deal with a key indicator length != 0 + AP4_OdafAtom* odaf = AP4_DYNAMIC_CAST(AP4_OdafAtom, schi->FindChild("odkm/odaf")); + if (odaf) { + if (odaf->GetIvLength() > AP4_CIPHER_BLOCK_SIZE) return AP4_ERROR_INVALID_FORMAT; + if (odaf->GetKeyIndicatorLength() != 0) return AP4_ERROR_INVALID_FORMAT; + } + + // check the scheme details and create the cipher + AP4_OhdrAtom* ohdr = AP4_DYNAMIC_CAST(AP4_OhdrAtom, schi->FindChild("odkm/ohdr")); + if (ohdr == NULL) return AP4_ERROR_INVALID_FORMAT; + AP4_UI08 encryption_method = ohdr->GetEncryptionMethod(); + if (encryption_method == AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CBC) { + // in CBC mode, we only support IVs of the same size as the cipher block size + if (odaf->GetIvLength() != AP4_CIPHER_BLOCK_SIZE) return AP4_ERROR_INVALID_FORMAT; + + // require RFC_2630 padding + if (ohdr->GetPaddingScheme() != AP4_OMA_DCF_PADDING_SCHEME_RFC_2630) { + return AP4_ERROR_NOT_SUPPORTED; + } + + // create the block cipher + AP4_BlockCipher* block_cipher = NULL; + AP4_Result result = block_cipher_factory->Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::DECRYPT, + key, + key_size, + block_cipher); + if (AP4_FAILED(result)) return result; + + // create the cipher + cipher = new AP4_OmaDcfCbcSampleDecrypter(block_cipher, + odaf->GetSelectiveEncryption()); + return AP4_SUCCESS; + } else if (encryption_method == AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CTR) { + // require NONE padding + if (ohdr->GetPaddingScheme() != AP4_OMA_DCF_PADDING_SCHEME_NONE) { + return AP4_ERROR_INVALID_FORMAT; + } + + // create the block cipher + AP4_BlockCipher* block_cipher = NULL; + AP4_Result result = block_cipher_factory->Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::ENCRYPT, + key, + key_size, + block_cipher); + if (AP4_FAILED(result)) return result; + + // create the cipher + cipher = new AP4_OmaDcfCtrSampleDecrypter(block_cipher, + odaf->GetIvLength(), + odaf->GetSelectiveEncryption()); + return AP4_SUCCESS; + } else { + return AP4_ERROR_NOT_SUPPORTED; + } +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleDecrypter::AP4_OmaDcfCtrSampleDecrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfCtrSampleDecrypter::AP4_OmaDcfCtrSampleDecrypter( + AP4_BlockCipher* block_cipher, + AP4_Size iv_length, + bool selective_encryption) : + AP4_OmaDcfSampleDecrypter(iv_length, selective_encryption) +{ + m_Cipher = new AP4_CtrStreamCipher(block_cipher, NULL, iv_length); +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleDecrypter::~AP4_OmaDcfCtrSampleDecrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfCtrSampleDecrypter::~AP4_OmaDcfCtrSampleDecrypter() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleDecrypter::DecryptSampleData ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfCtrSampleDecrypter::DecryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out) +{ + bool is_encrypted = true; + const unsigned char* in = data_in.GetData(); + AP4_Size in_size = data_in.GetDataSize(); + + // default to 0 output + data_out.SetDataSize(0); + + // check the selective encryption flag + if (m_SelectiveEncryption) { + if (in_size < 1) return AP4_ERROR_INVALID_FORMAT; + is_encrypted = ((in[0]&0x80)!=0); + in++; + } + + // check the size + unsigned int header_size = (m_SelectiveEncryption?1:0)+(is_encrypted?m_IvLength:0); + if (header_size > in_size) return AP4_ERROR_INVALID_FORMAT; + + // process the sample data + AP4_Size payload_size = in_size-header_size; + data_out.Reserve(payload_size); + unsigned char* out = data_out.UseData(); + if (is_encrypted) { + // set the IV + m_Cipher->SetIV(in); + AP4_CHECK(m_Cipher->ProcessBuffer(in+m_IvLength, + payload_size, + out)); + } else { + AP4_CopyMemory(out, in, payload_size); + } + data_out.SetDataSize(payload_size); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleDecrypter::GetDecryptedSampleSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_OmaDcfCtrSampleDecrypter::GetDecryptedSampleSize(AP4_Sample& sample) +{ + if (m_Cipher == NULL) return 0; + + // decide if this sample is encrypted or not + bool is_encrypted; + if (m_SelectiveEncryption) { + // read the first byte to see if the sample is encrypted or not + AP4_Byte h; + AP4_DataBuffer peek_buffer; + peek_buffer.SetBuffer(&h, 1); + sample.ReadData(peek_buffer, 1); + is_encrypted = ((h&0x80)!=0); + } else { + is_encrypted = true; + } + + AP4_Size crypto_header_size = (m_SelectiveEncryption?1:0)+(is_encrypted?m_IvLength:0); + return sample.GetSize()-crypto_header_size; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCbcSampleDecrypter::AP4_OmaDcfCbcSampleDecrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfCbcSampleDecrypter::AP4_OmaDcfCbcSampleDecrypter( + AP4_BlockCipher* block_cipher, + bool selective_encryption) : + AP4_OmaDcfSampleDecrypter(AP4_CIPHER_BLOCK_SIZE, selective_encryption) +{ + m_Cipher = new AP4_CbcStreamCipher(block_cipher, AP4_CbcStreamCipher::DECRYPT); +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCbcSampleDecrypter::~AP4_OmaDcfCbcSampleDecrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfCbcSampleDecrypter::~AP4_OmaDcfCbcSampleDecrypter() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDbcCbcSampleDecrypter::DecryptSampleData ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfCbcSampleDecrypter::DecryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out) +{ + bool is_encrypted = true; + const unsigned char* in = data_in.GetData(); + AP4_Size in_size = data_in.GetDataSize(); + AP4_Size out_size; + + // default to 0 output + data_out.SetDataSize(0); + + // check the selective encryption flag + if (m_SelectiveEncryption) { + if (in_size < 1) return AP4_ERROR_INVALID_FORMAT; + is_encrypted = ((in[0]&0x80)!=0); + in++; + } + + // check the size + unsigned int header_size = (m_SelectiveEncryption?1:0)+(is_encrypted?m_IvLength:0); + if (header_size > in_size) return AP4_ERROR_INVALID_FORMAT; + + // process the sample data + unsigned int payload_size = in_size-header_size; + data_out.Reserve(payload_size); + unsigned char* out = data_out.UseData(); + if (is_encrypted) { + // get the IV + const AP4_UI08* iv = (const AP4_UI08*)in; + in += AP4_CIPHER_BLOCK_SIZE; + + m_Cipher->SetIV(iv); + out_size = payload_size; + AP4_CHECK(m_Cipher->ProcessBuffer(in, payload_size, out, &out_size, true)); + } else { + AP4_CopyMemory(out, in, payload_size); + out_size = payload_size; + } + + data_out.SetDataSize(out_size); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCbcSampleDecrypter::GetDecryptedSampleSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_OmaDcfCbcSampleDecrypter::GetDecryptedSampleSize(AP4_Sample& sample) +{ + if (m_Cipher == NULL) return 0; + + // decide if this sample is encrypted or not + bool is_encrypted; + if (m_SelectiveEncryption) { + // read the first byte to see if the sample is encrypted or not + AP4_Byte h; + AP4_DataBuffer peek_buffer; + peek_buffer.SetBuffer(&h, 1); + sample.ReadData(peek_buffer, 1); + is_encrypted = ((h&0x80)!=0); + } else { + is_encrypted = true; + } + + if (is_encrypted) { + // with CBC, we need to decrypt the last block to know what the padding was + AP4_Size crypto_header_size = (m_SelectiveEncryption?1:0)+m_IvLength; + AP4_Size encrypted_size = sample.GetSize()-crypto_header_size; + AP4_DataBuffer encrypted; + AP4_DataBuffer decrypted; + AP4_Size decrypted_size = AP4_CIPHER_BLOCK_SIZE; + if (sample.GetSize() < crypto_header_size+AP4_CIPHER_BLOCK_SIZE) { + return 0; + } + AP4_Size offset = sample.GetSize()-2*AP4_CIPHER_BLOCK_SIZE; + if (AP4_FAILED(sample.ReadData(encrypted, 2*AP4_CIPHER_BLOCK_SIZE, offset))) { + return 0; + } + decrypted.Reserve(decrypted_size); + m_Cipher->SetIV(encrypted.GetData()); + if (AP4_FAILED(m_Cipher->ProcessBuffer(encrypted.GetData()+AP4_CIPHER_BLOCK_SIZE, + AP4_CIPHER_BLOCK_SIZE, + decrypted.UseData(), + &decrypted_size, + true))) { + return 0; + } + unsigned int padding_size = AP4_CIPHER_BLOCK_SIZE-decrypted_size; + return encrypted_size-padding_size; + } else { + return sample.GetSize()-(m_SelectiveEncryption?1:0); + } +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfSampleEncrypter::AP4_OmaDcfSampleEncrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfSampleEncrypter::AP4_OmaDcfSampleEncrypter(const AP4_UI08* salt) +{ + // left-align the salt + unsigned int i=0; + if (salt) { + for (; i<8; i++) { + m_Salt[i] = salt[i]; + } + } + for (; i<sizeof(m_Salt)/sizeof(m_Salt[0]); i++) { + m_Salt[i] = 0; + } +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleEncrypter::AP4_OmaDcfCtrSampleEncrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfCtrSampleEncrypter::AP4_OmaDcfCtrSampleEncrypter(AP4_BlockCipher* block_cipher, + const AP4_UI08* salt) : + AP4_OmaDcfSampleEncrypter(salt) +{ + m_Cipher = new AP4_CtrStreamCipher(block_cipher, m_Salt, 8); +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleEncrypter::~AP4_OmaDcfCtrSampleEncrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfCtrSampleEncrypter::~AP4_OmaDcfCtrSampleEncrypter() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleEncrypter::EncryptSampleData ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfCtrSampleEncrypter::EncryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out, + AP4_UI64 counter, + bool /*skip_encryption*/) +{ + // setup the buffers + const unsigned char* in = data_in.GetData(); + data_out.SetDataSize(data_in.GetDataSize()+AP4_CIPHER_BLOCK_SIZE+1); + unsigned char* out = data_out.UseData(); + + // selective encryption flag + *out++ = 0x80; + + // IV on 16 bytes: [SSSSSSSSXXXXXXXX] + // where SSSSSSSS is the 64-bit salt and + // XXXXXXXX is the 64-bit base counter + AP4_CopyMemory(out, m_Salt, 8); + AP4_BytesFromUInt64BE(&out[8], counter); + + // encrypt the payload + AP4_Size data_size = data_in.GetDataSize(); + m_Cipher->SetIV(out+8); + m_Cipher->ProcessBuffer(in, data_size, out+AP4_CIPHER_BLOCK_SIZE); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleEncrypter::GetEncryptedSampleSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_OmaDcfCtrSampleEncrypter::GetEncryptedSampleSize(AP4_Sample& sample) +{ + return sample.GetSize()+AP4_CIPHER_BLOCK_SIZE+1; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCbcSampleEncrypter::AP4_OmaDcfCbcSampleEncrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfCbcSampleEncrypter::AP4_OmaDcfCbcSampleEncrypter(AP4_BlockCipher* block_cipher, + const AP4_UI08* salt) : + AP4_OmaDcfSampleEncrypter(salt) +{ + m_Cipher = new AP4_CbcStreamCipher(block_cipher, AP4_CbcStreamCipher::ENCRYPT); +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCbcSampleEncrypter::~AP4_OmaDcfCbcSampleEncrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfCbcSampleEncrypter::~AP4_OmaDcfCbcSampleEncrypter() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCbcSampleEncrypter::EncryptSampleData ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfCbcSampleEncrypter::EncryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out, + AP4_UI64 counter, + bool /*skip_encryption*/) +{ + // make sure there is enough space in the output buffer + data_out.Reserve(data_in.GetDataSize()+2*AP4_CIPHER_BLOCK_SIZE+1); + + // setup the buffers + AP4_Size out_size = data_in.GetDataSize()+AP4_CIPHER_BLOCK_SIZE; + unsigned char* out = data_out.UseData(); + + // selective encryption flag + *out++ = 0x80; + + // IV on 16 bytes: [SSSSSSSSXXXXXXXX] + // where SSSSSSSS is the 64-bit salt and + // XXXXXXXX is the 64-bit base counter + AP4_CopyMemory(out, m_Salt, 8); + AP4_BytesFromUInt64BE(&out[8], counter); + + // encrypt the payload + m_Cipher->SetIV(out); + m_Cipher->ProcessBuffer(data_in.GetData(), + data_in.GetDataSize(), + out+AP4_CIPHER_BLOCK_SIZE, + &out_size, + true); + data_out.SetDataSize(out_size+AP4_CIPHER_BLOCK_SIZE+1); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCbcSampleEncrypter::GetEncryptedSampleSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_OmaDcfCbcSampleEncrypter::GetEncryptedSampleSize(AP4_Sample& sample) +{ + AP4_Size sample_size = sample.GetSize(); + AP4_Size padding_size = AP4_CIPHER_BLOCK_SIZE-(sample_size%AP4_CIPHER_BLOCK_SIZE); + return sample_size+padding_size+AP4_CIPHER_BLOCK_SIZE+1; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackDecrypter::Create ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfTrackDecrypter::Create( + const AP4_UI08* key, + AP4_Size key_size, + AP4_ProtectedSampleDescription* sample_description, + AP4_SampleEntry* sample_entry, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_OmaDcfTrackDecrypter*& decrypter) +{ + // check and set defaults + if (key == NULL) { + return AP4_ERROR_INVALID_PARAMETERS; + } + if (block_cipher_factory == NULL) { + block_cipher_factory = &AP4_DefaultBlockCipherFactory::Instance; + } + decrypter = NULL; + + // create the cipher + AP4_OmaDcfSampleDecrypter* cipher = NULL; + AP4_Result result = AP4_OmaDcfSampleDecrypter::Create(sample_description, + key, + key_size, + block_cipher_factory, + cipher); + if (AP4_FAILED(result)) return result; + + // instantiate the object + decrypter = new AP4_OmaDcfTrackDecrypter(cipher, + sample_entry, + sample_description->GetOriginalFormat()); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackDecrypter::AP4_OmaDcfTrackDecrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfTrackDecrypter::AP4_OmaDcfTrackDecrypter(AP4_OmaDcfSampleDecrypter* cipher, + AP4_SampleEntry* sample_entry, + AP4_UI32 original_format) : + m_Cipher(cipher), + m_SampleEntry(sample_entry), + m_OriginalFormat(original_format) +{ +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackDecrypter::~AP4_OmaDcfTrackDecrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfTrackDecrypter::~AP4_OmaDcfTrackDecrypter() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackDecrypter::GetProcessedSampleSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_OmaDcfTrackDecrypter::GetProcessedSampleSize(AP4_Sample& sample) +{ + if (m_Cipher == NULL) return 0; + return m_Cipher->GetDecryptedSampleSize(sample); +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackDecrypter::ProcessTrack ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfTrackDecrypter::ProcessTrack() +{ + m_SampleEntry->SetType(m_OriginalFormat); + m_SampleEntry->DeleteChild(AP4_ATOM_TYPE_SINF); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfDecrypter::ProcessSample ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfTrackDecrypter::ProcessSample(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out) +{ + return m_Cipher->DecryptSampleData(data_in, data_out); +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackEncrypter ++---------------------------------------------------------------------*/ +class AP4_OmaDcfTrackEncrypter : public AP4_Processor::TrackHandler { +public: + // constructor + AP4_OmaDcfTrackEncrypter(AP4_OmaDcfCipherMode cipher_mode, + AP4_BlockCipher* block_cipher, + const AP4_UI08* iv, + AP4_SampleEntry* sample_entry, + AP4_UI32 format, + const char* content_id, + const char* rights_issuer_url, + const AP4_Byte* textual_headers, + AP4_Size textual_headers_size); + virtual ~AP4_OmaDcfTrackEncrypter(); + + // methods + virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample); + virtual AP4_Result ProcessTrack(); + virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out); + +private: + // members + AP4_OmaDcfSampleEncrypter* m_Cipher; + AP4_UI08 m_CipherMode; + AP4_UI08 m_CipherPadding; + AP4_SampleEntry* m_SampleEntry; + AP4_UI32 m_Format; + AP4_String m_ContentId; + AP4_String m_RightsIssuerUrl; + AP4_DataBuffer m_TextualHeaders; + AP4_UI64 m_Counter; +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackEncrypter::AP4_OmaDcfTrackEncrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfTrackEncrypter::AP4_OmaDcfTrackEncrypter( + AP4_OmaDcfCipherMode cipher_mode, + AP4_BlockCipher* block_cipher, + const AP4_UI08* salt, + AP4_SampleEntry* sample_entry, + AP4_UI32 format, + const char* content_id, + const char* rights_issuer_url, + const AP4_Byte* textual_headers, + AP4_Size textual_headers_size) : + m_SampleEntry(sample_entry), + m_Format(format), + m_ContentId(content_id), + m_RightsIssuerUrl(rights_issuer_url), + m_TextualHeaders(textual_headers, textual_headers_size), + m_Counter(0) +{ + // instantiate the cipher (fixed params for now) + if (cipher_mode == AP4_OMA_DCF_CIPHER_MODE_CBC) { + m_Cipher = new AP4_OmaDcfCbcSampleEncrypter(block_cipher, salt); + m_CipherMode = AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CBC; + m_CipherPadding = AP4_OMA_DCF_PADDING_SCHEME_RFC_2630; + } else { + m_Cipher = new AP4_OmaDcfCtrSampleEncrypter(block_cipher, salt); + m_CipherMode = AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CTR; + m_CipherPadding = AP4_OMA_DCF_PADDING_SCHEME_NONE; + } +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackEncrypter::~AP4_OmaDcfTrackEncrypter ++---------------------------------------------------------------------*/ +AP4_OmaDcfTrackEncrypter::~AP4_OmaDcfTrackEncrypter() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackEncrypter::GetProcessedSampleSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_OmaDcfTrackEncrypter::GetProcessedSampleSize(AP4_Sample& sample) +{ + return m_Cipher->GetEncryptedSampleSize(sample); +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackEncrypter::ProcessTrack ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfTrackEncrypter::ProcessTrack() +{ + // sinf container + AP4_ContainerAtom* sinf = new AP4_ContainerAtom(AP4_ATOM_TYPE_SINF); + + // original format + AP4_FrmaAtom* frma = new AP4_FrmaAtom(m_SampleEntry->GetType()); + + // scheme info + AP4_ContainerAtom* schi = new AP4_ContainerAtom(AP4_ATOM_TYPE_SCHI); + AP4_OdafAtom* odaf = new AP4_OdafAtom(true, 0, AP4_CIPHER_BLOCK_SIZE); + AP4_OhdrAtom* ohdr = new AP4_OhdrAtom(m_CipherMode, + m_CipherPadding, + 0, + m_ContentId.GetChars(), + m_RightsIssuerUrl.GetChars(), + m_TextualHeaders.GetData(), + m_TextualHeaders.GetDataSize()); + AP4_ContainerAtom* odkm = new AP4_ContainerAtom(AP4_ATOM_TYPE_ODKM, (AP4_UI32)0, (AP4_UI32)0); + AP4_SchmAtom* schm = new AP4_SchmAtom(AP4_PROTECTION_SCHEME_TYPE_OMA, + AP4_PROTECTION_SCHEME_VERSION_OMA_20); + odkm->AddChild(odaf); + odkm->AddChild(ohdr); + + // populate the schi container + schi->AddChild(odkm); + + // populate the sinf container + sinf->AddChild(frma); + sinf->AddChild(schm); + sinf->AddChild(schi); + + // add the sinf atom to the sample description + m_SampleEntry->AddChild(sinf); + + // change the atom type of the sample description + m_SampleEntry->SetType(m_Format); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackEncrypter::ProcessSample ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfTrackEncrypter::ProcessSample(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out) +{ + AP4_Result result = m_Cipher->EncryptSampleData(data_in, + data_out, + m_Counter, + false); + if (AP4_FAILED(result)) return result; + + m_Counter += (data_in.GetDataSize()+AP4_CIPHER_BLOCK_SIZE-1)/AP4_CIPHER_BLOCK_SIZE; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfDecryptingProcessor:AP4_OmaDcfDecryptingProcessor ++---------------------------------------------------------------------*/ +AP4_OmaDcfDecryptingProcessor::AP4_OmaDcfDecryptingProcessor( + 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_OmaDcfDecryptingProcessor:Initialize ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfDecryptingProcessor::Initialize(AP4_AtomParent& top_level, + AP4_ByteStream& /* stream */, + ProgressListener* listener) +{ + // decide which processor to instantiate based on the file type + AP4_FtypAtom* ftyp = AP4_DYNAMIC_CAST(AP4_FtypAtom, top_level.GetChild(AP4_ATOM_TYPE_FTYP)); + if (ftyp) { + if (ftyp->GetMajorBrand() == AP4_OMA_DCF_BRAND_ODCF || ftyp->HasCompatibleBrand(AP4_OMA_DCF_BRAND_ODCF)) { + return AP4_OmaDcfAtomDecrypter::DecryptAtoms(top_level, listener, m_BlockCipherFactory, m_KeyMap); + } else { + return AP4_ERROR_INVALID_FORMAT; + } + } else { + return AP4_SUCCESS; + } +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfEncryptingProcessor:AP4_OmaDcfEncryptingProcessor ++---------------------------------------------------------------------*/ +AP4_OmaDcfEncryptingProcessor::AP4_OmaDcfEncryptingProcessor(AP4_OmaDcfCipherMode cipher_mode, + AP4_BlockCipherFactory* block_cipher_factory) : + m_CipherMode(cipher_mode) +{ + if (block_cipher_factory == NULL) { + m_BlockCipherFactory = &AP4_DefaultBlockCipherFactory::Instance; + } else { + m_BlockCipherFactory = block_cipher_factory; + } +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfEncryptingProcessor::Initialize ++---------------------------------------------------------------------*/ +AP4_Result +AP4_OmaDcfEncryptingProcessor::Initialize(AP4_AtomParent& top_level, + AP4_ByteStream& /*stream*/, + AP4_Processor::ProgressListener* /*listener*/) +{ + AP4_FtypAtom* ftyp = AP4_DYNAMIC_CAST(AP4_FtypAtom, top_level.GetChild(AP4_ATOM_TYPE_FTYP)); + if (ftyp) { + // remove the atom, it will be replaced with a new one + top_level.RemoveChild(ftyp); + + // keep the existing brand and compatible brands + AP4_Array<AP4_UI32> compatible_brands; + compatible_brands.EnsureCapacity(ftyp->GetCompatibleBrands().ItemCount()+1); + for (unsigned int i=0; i<ftyp->GetCompatibleBrands().ItemCount(); i++) { + compatible_brands.Append(ftyp->GetCompatibleBrands()[i]); + } + + // add the OMA compatible brand if it is not already there + if (!ftyp->HasCompatibleBrand(AP4_OMA_DCF_BRAND_OPF2)) { + compatible_brands.Append(AP4_OMA_DCF_BRAND_OPF2); + } + + // create a replacement + AP4_FtypAtom* new_ftyp = new AP4_FtypAtom(ftyp->GetMajorBrand(), + ftyp->GetMinorVersion(), + &compatible_brands[0], + compatible_brands.ItemCount()); + delete ftyp; + ftyp = new_ftyp; + } else { + AP4_UI32 isom = AP4_FTYP_BRAND_ISOM; + ftyp = new AP4_FtypAtom(AP4_OMA_DCF_BRAND_OPF2, 0, &isom, 1); + } + + // insert the ftyp atom as the first child + return top_level.AddChild(ftyp, 0); +} + +/*---------------------------------------------------------------------- +| AP4_OmaDcfEncryptingProcessor:CreateTrackHandler ++---------------------------------------------------------------------*/ +AP4_Processor::TrackHandler* +AP4_OmaDcfEncryptingProcessor::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; + + // only look at the first sample description + AP4_SampleEntry* entry = stsd->GetSampleEntry(0); + if (entry == NULL) return NULL; + + // create a handler for this track if we have a key for it and we know + // how to map the type + const AP4_UI08* key; + const AP4_UI08* iv; + AP4_UI32 format = 0; + if (AP4_SUCCEEDED(m_KeyMap.GetKeyAndIv(trak->GetId(), key, iv))) { + switch (entry->GetType()) { + case AP4_ATOM_TYPE_MP4A: + format = AP4_ATOM_TYPE_ENCA; + break; + + case AP4_ATOM_TYPE_MP4V: + case AP4_ATOM_TYPE_AVC1: + format = AP4_ATOM_TYPE_ENCV; + break; + } + if (format) { + const char* content_id = m_PropertyMap.GetProperty(trak->GetId(), "ContentId"); + const char* rights_issuer_url = m_PropertyMap.GetProperty(trak->GetId(), "RightsIssuerUrl"); + AP4_DataBuffer textual_headers; + AP4_Result result = m_PropertyMap.GetTextualHeaders(trak->GetId(), textual_headers); + if (AP4_FAILED(result)) textual_headers.SetDataSize(0); + + // create the block cipher + AP4_BlockCipher* block_cipher = NULL; + result = m_BlockCipherFactory->Create(AP4_BlockCipher::AES_128, + AP4_BlockCipher::ENCRYPT, + key, + AP4_CIPHER_BLOCK_SIZE, + block_cipher); + if (AP4_FAILED(result)) return NULL; + return new AP4_OmaDcfTrackEncrypter(m_CipherMode, + block_cipher, + iv, + entry, + format, + content_id, + rights_issuer_url, + textual_headers.GetData(), + textual_headers.GetDataSize()); + } + } + + return NULL; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OmaDcf.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OmaDcf.h new file mode 100644 index 000000000..146997211 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4OmaDcf.h @@ -0,0 +1,321 @@ +/***************************************************************** +| +| AP4 - OMA DCF 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_OMA_DCF_H_ +#define _AP4_OMA_DCF_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4SampleEntry.h" +#include "Ap4Atom.h" +#include "Ap4AtomFactory.h" +#include "Ap4SampleDescription.h" +#include "Ap4Processor.h" +#include "Ap4Protection.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_CtrStreamCipher; +class AP4_OdafAtom; +class AP4_StreamCipher; +class AP4_CbcStreamCipher; +class AP4_CtrStreamCipher; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_OMA = AP4_ATOM_TYPE('o','d','k','m'); +const AP4_UI32 AP4_PROTECTION_SCHEME_VERSION_OMA_20 = 0x00000200; +const AP4_UI32 AP4_OMA_DCF_BRAND_ODCF = AP4_ATOM_TYPE('o','d','c','f'); +const AP4_UI32 AP4_OMA_DCF_BRAND_OPF2 = AP4_ATOM_TYPE('o','p','f','2'); + +typedef enum { + AP4_OMA_DCF_CIPHER_MODE_CTR, + AP4_OMA_DCF_CIPHER_MODE_CBC +} AP4_OmaDcfCipherMode; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfAtomDecrypter ++---------------------------------------------------------------------*/ +class AP4_OmaDcfAtomDecrypter { +public: + // class methods + static AP4_Result DecryptAtoms(AP4_AtomParent& atoms, + AP4_Processor::ProgressListener* listener, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ProtectionKeyMap& key_map); + + // Returns a byte stream that will produce the decrypted data found + // in the 'odda' child atom of an 'odrm' atom + static AP4_Result CreateDecryptingStream(AP4_ContainerAtom& odrm_atom, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ByteStream*& stream); + + // Returns a byte stream that will produce the decrypted data from + // an encrypted stream where the IV follows the encrypted bytes. + // This method is normally not called directly: most callers will call + // the stream factory that takes an 'odrm' atom as an input parameter + static AP4_Result CreateDecryptingStream(AP4_OmaDcfCipherMode mode, + AP4_ByteStream& encrypted_stream, + AP4_LargeSize cleartext_size, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_ByteStream*& stream); +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfSampleDecrypter ++---------------------------------------------------------------------*/ +class AP4_OmaDcfSampleDecrypter : public AP4_SampleDecrypter +{ +public: + // factory + static AP4_Result Create(AP4_ProtectedSampleDescription* sample_description, + const AP4_UI08* key, + AP4_Size key_size, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_OmaDcfSampleDecrypter*& cipher); + + // constructor and destructor + AP4_OmaDcfSampleDecrypter(AP4_Size iv_length, + bool selective_encryption) : + m_IvLength(iv_length), + m_SelectiveEncryption(selective_encryption) {} + +protected: + AP4_Size m_IvLength; + AP4_Size m_KeyIndicatorLength; + bool m_SelectiveEncryption; +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleDecrypter ++---------------------------------------------------------------------*/ +class AP4_OmaDcfCtrSampleDecrypter : public AP4_OmaDcfSampleDecrypter +{ +public: + // constructor and destructor + AP4_OmaDcfCtrSampleDecrypter(AP4_BlockCipher* block_cipher, + AP4_Size iv_length, + bool selective_encryption); + ~AP4_OmaDcfCtrSampleDecrypter(); + + // methods + virtual AP4_Result DecryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out); + virtual AP4_Size GetDecryptedSampleSize(AP4_Sample& sample); + +private: + // members + AP4_CtrStreamCipher* m_Cipher; +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCbcSampleDecrypter ++---------------------------------------------------------------------*/ +class AP4_OmaDcfCbcSampleDecrypter : public AP4_OmaDcfSampleDecrypter +{ +public: + // constructor and destructor + AP4_OmaDcfCbcSampleDecrypter(AP4_BlockCipher* block_cipher, + bool selective_encryption); + ~AP4_OmaDcfCbcSampleDecrypter(); + + // methods + virtual AP4_Result DecryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out); + virtual AP4_Size GetDecryptedSampleSize(AP4_Sample& sample); + +private: + // members + AP4_CbcStreamCipher* m_Cipher; +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfTrackDecrypter ++---------------------------------------------------------------------*/ +class AP4_OmaDcfTrackDecrypter : public AP4_Processor::TrackHandler { +public: + // constructor + static AP4_Result Create(const AP4_UI08* key, + AP4_Size key_size, + AP4_ProtectedSampleDescription* sample_description, + AP4_SampleEntry* sample_entry, + AP4_BlockCipherFactory* block_cipher_factory, + AP4_OmaDcfTrackDecrypter*& decrypter); + virtual ~AP4_OmaDcfTrackDecrypter(); + + // methods + virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample); + virtual AP4_Result ProcessTrack(); + virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out); + +private: + // constructor + AP4_OmaDcfTrackDecrypter(AP4_OmaDcfSampleDecrypter* cipher, + AP4_SampleEntry* sample_entry, + AP4_UI32 original_format); + + // members + AP4_OmaDcfSampleDecrypter* m_Cipher; + AP4_SampleEntry* m_SampleEntry; + AP4_UI32 m_OriginalFormat; +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfSampleEncrypter ++---------------------------------------------------------------------*/ +class AP4_OmaDcfSampleEncrypter +{ +public: + // constructor and destructor + AP4_OmaDcfSampleEncrypter(const AP4_UI08* salt); // salt is only 8 bytes + virtual ~AP4_OmaDcfSampleEncrypter() {} + + // methods + virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out, + AP4_UI64 bso, + bool skip_encryption) = 0; + virtual AP4_Size GetEncryptedSampleSize(AP4_Sample& sample) = 0; + +protected: + // members + AP4_UI08 m_Salt[16]; +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCtrSampleEncrypter ++---------------------------------------------------------------------*/ +class AP4_OmaDcfCtrSampleEncrypter : public AP4_OmaDcfSampleEncrypter +{ +public: + // constructor and destructor + AP4_OmaDcfCtrSampleEncrypter(AP4_BlockCipher* block_cipher, + const AP4_UI08* salt); // salt is only 8 bytes + ~AP4_OmaDcfCtrSampleEncrypter(); + + // methods + virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out, + AP4_UI64 bso, + bool skip_encryption); + virtual AP4_Size GetEncryptedSampleSize(AP4_Sample& sample); + +private: + // members + AP4_CtrStreamCipher* m_Cipher; +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfCbcSampleEncrypter ++---------------------------------------------------------------------*/ +class AP4_OmaDcfCbcSampleEncrypter : public AP4_OmaDcfSampleEncrypter +{ +public: + // constructor and destructor + AP4_OmaDcfCbcSampleEncrypter(AP4_BlockCipher* block_cipher, + const AP4_UI08* salt); // salt is only 8 bytes + ~AP4_OmaDcfCbcSampleEncrypter(); + + // methods + virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out, + AP4_UI64 bso, + bool skip_encryption); + virtual AP4_Size GetEncryptedSampleSize(AP4_Sample& sample); + +private: + // members + AP4_CbcStreamCipher* m_Cipher; +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfDecryptingProcessor ++---------------------------------------------------------------------*/ +/** + * Use for DCF only, not PDCF. For PDCF, use the + * AP4_StandardDecryptingProcessor class + */ +class AP4_OmaDcfDecryptingProcessor : public AP4_Processor +{ +public: + // constructor + AP4_OmaDcfDecryptingProcessor(const AP4_ProtectionKeyMap* key_map = NULL, + AP4_BlockCipherFactory* block_cipher_factory = NULL); + + // accessors + AP4_ProtectionKeyMap& GetKeyMap() { return m_KeyMap; } + + // methods + virtual AP4_Result Initialize(AP4_AtomParent& top_level, + AP4_ByteStream& stream, + ProgressListener* listener); + +private: + // members + AP4_BlockCipherFactory* m_BlockCipherFactory; + AP4_ProtectionKeyMap m_KeyMap; +}; + +/*---------------------------------------------------------------------- +| AP4_OmaDcfEncryptingProcessor ++---------------------------------------------------------------------*/ +class AP4_OmaDcfEncryptingProcessor : public AP4_Processor +{ +public: + // constructor + AP4_OmaDcfEncryptingProcessor(AP4_OmaDcfCipherMode cipher_mode, + AP4_BlockCipherFactory* block_cipher_factory = NULL); + + // accessors + AP4_ProtectionKeyMap& GetKeyMap() { return m_KeyMap; } + AP4_TrackPropertyMap& GetPropertyMap() { return m_PropertyMap; } + + // AP4_Processor methods + virtual AP4_Result Initialize(AP4_AtomParent& top_level, + AP4_ByteStream& stream, + AP4_Processor::ProgressListener* listener = NULL); + virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak); + +private: + // members + AP4_OmaDcfCipherMode m_CipherMode; + AP4_BlockCipherFactory* m_BlockCipherFactory; + AP4_ProtectionKeyMap m_KeyMap; + AP4_TrackPropertyMap m_PropertyMap; +}; + +#endif // _AP4_OMA_DCF_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Processor.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Processor.cpp index ec2918ac2..771eeed77 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Processor.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Processor.cpp @@ -2,7 +2,7 @@ | | AP4 - File Processor | -| Copyright 2003-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,60 +27,63 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Processor.h" #include "Ap4AtomSampleTable.h" #include "Ap4AtomFactory.h" -#include "Ap4MoovAtom.h" +#include "Ap4Movie.h" #include "Ap4Array.h" +#include "Ap4Sample.h" +#include "Ap4TrakAtom.h" +#include "Ap4DataBuffer.h" #include "Ap4Debug.h" /*---------------------------------------------------------------------- -| types +| types +---------------------------------------------------------------------*/ -class AP4_SampleLocator { -public: +struct AP4_SampleLocator { AP4_SampleLocator() : m_TrakIndex(0), m_SampleTable(NULL), m_SampleIndex(0), - m_Chunk(0) {} - + m_ChunkIndex(0) {} AP4_Ordinal m_TrakIndex; AP4_AtomSampleTable* m_SampleTable; AP4_Ordinal m_SampleIndex; + AP4_Ordinal m_ChunkIndex; AP4_Sample m_Sample; - AP4_Ordinal m_Chunk; }; struct AP4_SampleCursor { + AP4_SampleCursor() : m_EndReached(false) {} AP4_SampleLocator m_Locator; + bool m_EndReached; }; /*---------------------------------------------------------------------- -| AP4_Processor::Process +| AP4_Processor::Process +---------------------------------------------------------------------*/ AP4_Result -AP4_Processor::Process(AP4_ByteStream& input, - AP4_ByteStream& output, - AP4_AtomFactory& atom_factory) +AP4_Processor::Process(AP4_ByteStream& input, + AP4_ByteStream& output, + ProgressListener* listener, + AP4_AtomFactory& atom_factory) { // read all atoms AP4_AtomParent top_level; - AP4_Atom* atom; + AP4_Atom* atom; while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(input, atom))) { top_level.AddChild(atom); } - // remove the [mdat] and [free] atoms, keep a ref to [moov] + // remove the [mdat] atom, keep a ref to [moov] AP4_MoovAtom* moov = NULL; AP4_List<AP4_Atom>::Item* atom_item = top_level.GetChildren().FirstItem(); while (atom_item) { atom = atom_item->GetData(); AP4_List<AP4_Atom>::Item* next = atom_item->GetNext(); - if (//atom->GetType() == AP4_ATOM_TYPE_FREE || - atom->GetType() == AP4_ATOM_TYPE_MDAT) { + if (atom->GetType() == AP4_ATOM_TYPE_MDAT) { atom->Detach(); delete atom; } else if (atom->GetType() == AP4_ATOM_TYPE_MOOV) { @@ -89,194 +92,235 @@ AP4_Processor::Process(AP4_ByteStream& input, atom_item = next; } - // check that we have a moov atom - if (moov == NULL) return AP4_FAILURE; - // initialize the processor - AP4_Result result = Initialize(top_level); + AP4_Result result = Initialize(top_level, input); if (AP4_FAILED(result)) return result; - // build an array of track sample cursors - AP4_List<AP4_TrakAtom>& trak_atoms = moov->GetTrakAtoms(); - AP4_Cardinal track_count = trak_atoms.ItemCount(); - AP4_SampleCursor* cursors = DNew AP4_SampleCursor[track_count]; - TrackHandler** handlers = DNew TrackHandler*[track_count]; - AP4_List<AP4_TrakAtom>::Item* item = trak_atoms.FirstItem(); - unsigned int index = 0; - while (item) { - // create the track handler // find the stsd atom - AP4_ContainerAtom* stbl = dynamic_cast<AP4_ContainerAtom*>( - item->GetData()->FindChild("mdia/minf/stbl")); - if (stbl == NULL) continue; - handlers[index] = CreateTrackHandler(item->GetData()); - cursors[index].m_Locator.m_TrakIndex = index; - cursors[index].m_Locator.m_SampleTable = DNew AP4_AtomSampleTable(stbl, input); - cursors[index].m_Locator.m_SampleIndex = 0; - cursors[index].m_Locator.m_SampleTable->GetSample(0, cursors[index].m_Locator.m_Sample); - cursors[index].m_Locator.m_Chunk = 1; - index++; - item = item->GetNext(); - } - - // figure out the layout of the chunks + // process the tracks if we have a moov atom AP4_Array<AP4_SampleLocator> locators; - for (;;) { - // see which is the next sample to write - unsigned int min_offset = 0xFFFFFFFF; - int cursor = -1; - for (unsigned int i=0; i<track_count; i++) { - if (cursors[i].m_Locator.m_SampleTable && - cursors[i].m_Locator.m_Sample.GetOffset() <= min_offset) { + AP4_Cardinal track_count = 0; + AP4_List<AP4_TrakAtom>* trak_atoms = NULL; + AP4_LargeSize mdat_payload_size = 0; + TrackHandler** handlers = NULL; + AP4_SampleCursor* cursors = NULL; + if (moov) { + // build an array of track sample locators + trak_atoms = &moov->GetTrakAtoms(); + track_count = trak_atoms->ItemCount(); + cursors = new AP4_SampleCursor[track_count]; + handlers = new TrackHandler*[track_count]; + for (AP4_Ordinal i=0; i<track_count; i++) { + handlers[i] = NULL; + } + + unsigned int index = 0; + for (AP4_List<AP4_TrakAtom>::Item* item = trak_atoms->FirstItem(); item; item=item->GetNext()) { + AP4_TrakAtom* trak = item->GetData(); + + // find the stsd atom + AP4_ContainerAtom* stbl = AP4_DYNAMIC_CAST(AP4_ContainerAtom, trak->FindChild("mdia/minf/stbl")); + if (stbl == NULL) continue; + + // see if there's an external data source for this track + AP4_ByteStream* trak_data_stream = &input; + for (AP4_List<ExternalTrackData>::Item* ditem = m_ExternalTrackData.FirstItem(); ditem; ditem=ditem->GetNext()) { + ExternalTrackData* tdata = ditem->GetData(); + if (tdata->m_TrackId == trak->GetId()) { + trak_data_stream = tdata->m_MediaData; + break; + } + } + + // create the track handler + handlers[index] = CreateTrackHandler(trak); + cursors[index].m_Locator.m_TrakIndex = index; + cursors[index].m_Locator.m_SampleTable = new AP4_AtomSampleTable(stbl, *trak_data_stream); + cursors[index].m_Locator.m_SampleIndex = 0; + cursors[index].m_Locator.m_ChunkIndex = 0; + cursors[index].m_Locator.m_SampleTable->GetSample(0, cursors[index].m_Locator.m_Sample); + + index++; + } + + // figure out the layout of the chunks + for (;;) { + // see which is the next sample to write + AP4_UI64 min_offset = (AP4_UI64)(-1); + int cursor = -1; + for (unsigned int i=0; i<track_count; i++) { + if (!cursors[i].m_EndReached && + cursors[i].m_Locator.m_Sample.GetOffset() <= min_offset) { min_offset = cursors[i].m_Locator.m_Sample.GetOffset(); cursor = i; + } } - } - // stop if all cursors are exhausted - if (cursor == -1) break; + // stop if all cursors are exhausted + if (cursor == -1) break; - // append this locator to the layout list - AP4_SampleLocator& locator = cursors[cursor].m_Locator; - locators.Append(locator); - //AP4_Debug("NEXT: track %d, sample %d:%d: offset=%d, size=%d\n", - // locator.m_TrakIndex, - // locator.m_Chunk, - // locator.m_SampleIndex, - // locator.m_Sample.GetOffset(), - // locator.m_Sample.GetSize()); + // append this locator to the layout list + AP4_SampleLocator& locator = cursors[cursor].m_Locator; + locators.Append(locator); - // move the cursor to the next sample - locator.m_SampleIndex++; - if (locator.m_SampleIndex == locator.m_SampleTable->GetSampleCount()) { - // mark this track as completed - locator.m_SampleTable = NULL; - } else { - // get the next sample info - locator.m_SampleTable->GetSample(locator.m_SampleIndex, - locator.m_Sample); - AP4_Ordinal skip, sdesc; - locator.m_SampleTable->GetChunkForSample(locator.m_SampleIndex+1, // the internal API is 1-based - locator.m_Chunk, - skip, sdesc); + // move the cursor to the next sample + locator.m_SampleIndex++; + if (locator.m_SampleIndex == locator.m_SampleTable->GetSampleCount()) { + // mark this track as completed + cursors[cursor].m_EndReached = true; + } else { + // get the next sample info + locator.m_SampleTable->GetSample(locator.m_SampleIndex, locator.m_Sample); + AP4_Ordinal skip, sdesc; + locator.m_SampleTable->GetChunkForSample(locator.m_SampleIndex, + locator.m_ChunkIndex, + skip, sdesc); + } } - } - // update the stbl atoms and compute the mdat size - AP4_Size mdat_size = 0; - int current_track = -1; - int current_chunk = -1; - AP4_Offset current_chunk_offset = 0; - AP4_Size current_chunk_size = 0; - for (AP4_Ordinal i=0; i<locators.ItemCount(); i++) { - AP4_SampleLocator& locator = locators[i]; - if ((int)locator.m_TrakIndex != current_track || - (int)locator.m_Chunk != current_chunk) { - // start a new chunk for this track - current_chunk_offset += current_chunk_size; - current_chunk_size = 0; - current_track = locator.m_TrakIndex; - current_chunk = locator.m_Chunk; - locator.m_SampleTable->SetChunkOffset(locator.m_Chunk, - current_chunk_offset); - } - AP4_Size sample_size; - TrackHandler* handler = handlers[locator.m_TrakIndex]; - if (handler) { - sample_size = handler->GetProcessedSampleSize(locator.m_Sample); - locator.m_SampleTable->SetSampleSize(locator.m_SampleIndex+1, sample_size); - } else { - sample_size = locator.m_Sample.GetSize(); + // update the stbl atoms and compute the mdat size + int current_track = -1; + int current_chunk = -1; + AP4_Position current_chunk_offset = 0; + AP4_Size current_chunk_size = 0; + for (AP4_Ordinal i=0; i<locators.ItemCount(); i++) { + AP4_SampleLocator& locator = locators[i]; + if ((int)locator.m_TrakIndex != current_track || + (int)locator.m_ChunkIndex != current_chunk) { + // start a new chunk for this track + current_chunk_offset += current_chunk_size; + current_chunk_size = 0; + current_track = locator.m_TrakIndex; + current_chunk = locator.m_ChunkIndex; + locator.m_SampleTable->SetChunkOffset(locator.m_ChunkIndex, current_chunk_offset); + } + AP4_Size sample_size; + TrackHandler* handler = handlers[locator.m_TrakIndex]; + if (handler) { + sample_size = handler->GetProcessedSampleSize(locator.m_Sample); + locator.m_SampleTable->SetSampleSize(locator.m_SampleIndex, sample_size); + } else { + sample_size = locator.m_Sample.GetSize(); + } + current_chunk_size += sample_size; + mdat_payload_size += sample_size; } - current_chunk_size += sample_size; - mdat_size += sample_size; - } - // process the tracks (ex: sample descriptions processing) - for (AP4_Ordinal i=0; i<track_count; i++) { - TrackHandler* handler = handlers[i]; - if (handler) handler->ProcessTrack(); + // process the tracks (ex: sample descriptions processing) + for (AP4_Ordinal i=0; i<track_count; i++) { + TrackHandler* handler = handlers[i]; + if (handler) handler->ProcessTrack(); + } } // initialize the processor Finalize(top_level); // calculate the size of all atoms combined - AP4_Size atoms_size = 0; + AP4_UI64 atoms_size = 0; top_level.GetChildren().Apply(AP4_AtomSizeAdder(atoms_size)); + // see if we need a 64-bit or 32-bit mdat + AP4_Size mdat_header_size = AP4_ATOM_HEADER_SIZE; + if (mdat_payload_size+mdat_header_size > 0xFFFFFFFF) { + // we need a 64-bit size + mdat_header_size += 8; + } + // adjust the chunk offsets for (AP4_Ordinal i=0; i<track_count; i++) { AP4_TrakAtom* trak; - trak_atoms.Get(i, trak); - trak->AdjustChunkOffsets(atoms_size+AP4_ATOM_HEADER_SIZE); + trak_atoms->Get(i, trak); + trak->AdjustChunkOffsets(atoms_size+mdat_header_size); } // write all atoms top_level.GetChildren().Apply(AP4_AtomListWriter(output)); // write mdat header - output.WriteUI32(mdat_size+AP4_ATOM_HEADER_SIZE); - output.WriteUI32(AP4_ATOM_TYPE_MDAT); - + if (mdat_payload_size) { + if (mdat_header_size == AP4_ATOM_HEADER_SIZE) { + // 32-bit size + output.WriteUI32((AP4_UI32)(mdat_header_size+mdat_payload_size)); + output.WriteUI32(AP4_ATOM_TYPE_MDAT); + } else { + // 64-bit size + output.WriteUI32(1); + output.WriteUI32(AP4_ATOM_TYPE_MDAT); + output.WriteUI64(mdat_header_size+mdat_payload_size); + } + } + #if defined(AP4_DEBUG) - AP4_Offset before; + AP4_Position before; output.Tell(before); #endif // write the samples - AP4_Sample sample; - AP4_DataBuffer data_in; - AP4_DataBuffer data_out; - for (unsigned int i=0; i<locators.ItemCount(); i++) { - AP4_SampleLocator& locator = locators[i]; - locator.m_Sample.ReadData(data_in); - TrackHandler* handler = handlers[locator.m_TrakIndex]; - if (handler) { - handler->ProcessSample(data_in, data_out); - output.Write(data_out.GetData(), data_out.GetDataSize()); - } else { - output.Write(data_in.GetData(), data_in.GetDataSize()); + if (moov) { + AP4_Sample sample; + AP4_DataBuffer data_in; + AP4_DataBuffer data_out; + for (unsigned int i=0; i<locators.ItemCount(); i++) { + AP4_SampleLocator& locator = locators[i]; + locator.m_Sample.ReadData(data_in); + TrackHandler* handler = handlers[locator.m_TrakIndex]; + if (handler) { + result = handler->ProcessSample(data_in, data_out); + if (AP4_FAILED(result)) return result; + output.Write(data_out.GetData(), data_out.GetDataSize()); + } else { + output.Write(data_in.GetData(), data_in.GetDataSize()); + } + + // notify the progress listener + if (listener) { + listener->OnProgress(i+1, locators.ItemCount()); + } } + + // cleanup + for (AP4_Ordinal i=0; i<track_count; i++) { + delete cursors[i].m_Locator.m_SampleTable; + delete handlers[i]; + } + delete[] cursors; + delete[] handlers; } #if defined(AP4_DEBUG) - AP4_Offset after; + AP4_Position after; output.Tell(after); - AP4_ASSERT(after-before == mdat_size); + AP4_ASSERT(after-before == mdat_payload_size); #endif - // cleanup - delete[] cursors; - for (unsigned int i=0; i<track_count; i++) { - delete handlers[i]; - } - delete[] handlers; - return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_Processor:Initialize +| AP4_Processor:Initialize +---------------------------------------------------------------------*/ AP4_Result -AP4_Processor::Initialize(AP4_AtomParent& top_level) +AP4_Processor::Initialize(AP4_AtomParent& /* top_level */, + AP4_ByteStream& /* stream */, + ProgressListener* /* listener */) { // default implementation: do nothing return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_Processor:Finalize +| AP4_Processor:Finalize +---------------------------------------------------------------------*/ AP4_Result -AP4_Processor::Finalize(AP4_AtomParent& top_level) +AP4_Processor::Finalize(AP4_AtomParent& /* top_level */, + ProgressListener* /* listener */ ) { // default implementation: do nothing return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_Processor:CreateTrackHandler +| AP4_Processor:CreateTrackHandler +---------------------------------------------------------------------*/ AP4_Processor::TrackHandler* AP4_Processor::CreateTrackHandler(AP4_TrakAtom* /* trak */) @@ -286,7 +330,7 @@ AP4_Processor::CreateTrackHandler(AP4_TrakAtom* /* trak */) } /*---------------------------------------------------------------------- -| AP4_Processor::TrackHandler::GetProcessedSampleSize +| AP4_Processor::TrackHandler::GetProcessedSampleSize +---------------------------------------------------------------------*/ AP4_Size AP4_Processor::TrackHandler::GetProcessedSampleSize(AP4_Sample& sample) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Processor.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Processor.h index 7d1f03d4f..d6bde6e7c 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Processor.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Processor.h @@ -2,7 +2,7 @@ | | AP4 - File Processor | -| Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -26,14 +26,19 @@ | ****************************************************************/ +#ifndef _AP4_PROCESSOR_H_ +#define _AP4_PROCESSOR_H_ + /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" +#include "Ap4Types.h" #include "Ap4AtomFactory.h" +#include "Ap4File.h" +#include "Ap4Track.h" /*---------------------------------------------------------------------- -| class references +| class references +---------------------------------------------------------------------*/ class AP4_ContainerAtom; class AP4_Sample; @@ -42,31 +47,131 @@ class AP4_DataBuffer; class AP4_TrakAtom; /*---------------------------------------------------------------------- -| AP4_Processor +| AP4_Processor +---------------------------------------------------------------------*/ class AP4_Processor { public: - // types + /** + * Abstract class that defines the interface implemented by progress + * listeners. A progress listener is called during the AP4_Processor::Process() + * method to notify of progres information. + */ + class ProgressListener { + public: + virtual ~ProgressListener() {} + + /** + * This method is called during the call to AP4_Processor::Process() to + * notify of the progress of the operation. If this method returns an + * error result, processing is aborted. + * @param step Ordinal of the current progress step. + * @param total Total number of steps. + * @return A result code. If this method returns AP4_SUCCESS, the + * processing continues. If an error code is returned, the processing + * is aborted. + */ + virtual AP4_Result OnProgress(unsigned int step, + unsigned int total) = 0; + }; + + /** + * Abstract class that defines the interface implemented by concrete + * track handlers. A track handler is responsible for processing a + * track and its media samples. + */ class TrackHandler { public: + /** + * Default destructor. + */ virtual ~TrackHandler() {} + + /** + * Returns the size of a sample after processing. + * @param sample Sample of which the processed size is requested. + * @return Size of the sample data after processing. + */ virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample); + + /** + * A track handler may override this method if it needs to modify + * the track atoms before processing the track samples. + */ virtual AP4_Result ProcessTrack() { return AP4_SUCCESS; } + + /** + * Process the data of one sample. + * @param data_in Data buffer with the data of the sample to process. + * @param data_out Data buffer in which the processed sample data is + * returned. + */ virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in, AP4_DataBuffer& data_out) = 0; }; - // constructor and destructor - virtual ~AP4_Processor() {} + /** + * Default destructor + */ + virtual ~AP4_Processor() { m_ExternalTrackData.DeleteReferences(); } + + /** + * Process the input stream into an output stream. + * @param input Reference to the file to process. + * @param output Output stream to which the processed input + * will be written. + * @param listener Pointer to a listener, or NULL. The listener + * will be called one or more times before this method returns, + * with progress information. + */ + AP4_Result Process(AP4_ByteStream& input, + AP4_ByteStream& output, + ProgressListener* listener = NULL, + AP4_AtomFactory& atom_factory = + AP4_DefaultAtomFactory::Instance); + + /** + * This method can be overridden by concrete subclasses. + * It is called just after the input stream has been parsed into + * an atom tree, before the processing of the tracks. + * @param top_level Container atom containing all the atoms parsed + * from the input stream. Note that this atom does not actually + * exist in the file; it is a synthetised container created for the + * purpose of holding together all the input's top-level atoms. + */ + virtual AP4_Result Initialize(AP4_AtomParent& top_level, + AP4_ByteStream& stream, + ProgressListener* listener = NULL); - // abstract base class methods - AP4_Result Process(AP4_ByteStream& input, - AP4_ByteStream& output, - AP4_AtomFactory& atom_factory = - AP4_AtomFactory::DefaultFactory); + /** + * This method can be overridden by concrete subclasses. + * It is called just after the tracks have been processed. + */ + virtual AP4_Result Finalize(AP4_AtomParent& top_level, + ProgressListener* listener = NULL); - // overridable methods - virtual AP4_Result Initialize(AP4_AtomParent& top_level); - virtual AP4_Result Finalize(AP4_AtomParent& top_level); + /** + * This method can be overridden by concrete subclasses. + * It is called once for each track in the input file. + * @param track Pointer to the track for which a handler should be + * created. + * @return A pointer to a track handler, or NULL if not handler + * needs to be created for that track. + */ virtual TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak); + +protected: + class ExternalTrackData { + public: + ExternalTrackData(unsigned int track_id, AP4_ByteStream* media_data) : + m_TrackId(track_id), m_MediaData(media_data) { + media_data->AddReference(); + } + ~ExternalTrackData() { m_MediaData->Release(); } + unsigned int m_TrackId; + AP4_ByteStream* m_MediaData; + }; + + AP4_List<ExternalTrackData> m_ExternalTrackData; }; + +#endif // _AP4_PROCESSOR_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Results.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Results.h index 21d3cf5ed..0f7d3d955 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Results.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Results.h @@ -2,7 +2,7 @@ | | AP4 - Result Codes | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,7 +30,7 @@ #define _AP4_RESULTS_H_ /*---------------------------------------------------------------------- -| constants +| constants +---------------------------------------------------------------------*/ const int AP4_SUCCESS = 0; const int AP4_FAILURE = -1; @@ -50,14 +50,26 @@ const int AP4_ERROR_INVALID_STATE = -14; const int AP4_ERROR_LIST_EMPTY = -15; const int AP4_ERROR_LIST_OPERATION_ABORTED = -16; const int AP4_ERROR_INVALID_RTP_CONSTRUCTOR_TYPE = -17; -const int AP4_ERROR_NOT_SUPPORTED_YET = -18; +const int AP4_ERROR_NOT_SUPPORTED = -18; const int AP4_ERROR_INVALID_TRACK_TYPE = -19; const int AP4_ERROR_INVALID_RTP_PACKET_EXTRA_DATA = -20; +const int AP4_ERROR_BUFFER_TOO_SMALL = -21; +const int AP4_ERROR_NOT_ENOUGH_DATA = -22; /*---------------------------------------------------------------------- -| macros +| utility functions ++---------------------------------------------------------------------*/ +const char* AP4_ResultText(int result); + +/*---------------------------------------------------------------------- +| macros +---------------------------------------------------------------------*/ #define AP4_FAILED(result) ((result) != AP4_SUCCESS) #define AP4_SUCCEEDED(result) ((result) == AP4_SUCCESS) +#define AP4_CHECK(_x) do { \ + AP4_Result _result = (_x); \ + if (AP4_FAILED(_result)) return _result; \ +} while(0) + #endif // _AP4_RESULTS_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpAtom.cpp index 676792810..ad46363cd 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - sdp Atoms | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,19 +27,18 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4RtpAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_RtpAtom::AP4_RtpAtom +| AP4_RtpAtom::AP4_RtpAtom +---------------------------------------------------------------------*/ -AP4_RtpAtom::AP4_RtpAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_RTP, size, false, stream) +AP4_RtpAtom::AP4_RtpAtom(AP4_UI32 size, AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_RTP_, size) { // desc format stream.ReadUI32(m_DescriptionFormat); @@ -47,7 +46,7 @@ AP4_RtpAtom::AP4_RtpAtom(AP4_Size size, AP4_ByteStream& stream) : // sdptext int str_size = size-(AP4_ATOM_HEADER_SIZE+4); if (str_size) { - char* str = DNew char[str_size+1]; + char* str = new char[str_size+1]; stream.Read(str, str_size); str[str_size] = '\0'; // force null-termination m_SdpText = str; @@ -56,7 +55,7 @@ AP4_RtpAtom::AP4_RtpAtom(AP4_Size size, AP4_ByteStream& stream) : } /*---------------------------------------------------------------------- -| AP4_RtpAtom::WriteFields +| AP4_RtpAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_RtpAtom::WriteFields(AP4_ByteStream& stream) @@ -68,18 +67,18 @@ AP4_RtpAtom::WriteFields(AP4_ByteStream& stream) if (AP4_FAILED(result)) return result; // sdp text - result = stream.Write(m_SdpText.c_str(), m_SdpText.length()); + result = stream.Write(m_SdpText.GetChars(), m_SdpText.GetLength()); if (AP4_FAILED(result)) return result; // pad with zeros if necessary - AP4_Size padding = m_Size-(AP4_ATOM_HEADER_SIZE+4+m_SdpText.length()); + AP4_Size padding = m_Size32-(AP4_ATOM_HEADER_SIZE+4+m_SdpText.GetLength()); while (padding--) stream.WriteUI08(0); return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_RtpAtom::InspectFields +| AP4_RtpAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_RtpAtom::InspectFields(AP4_AtomInspector& inspector) @@ -87,7 +86,7 @@ AP4_RtpAtom::InspectFields(AP4_AtomInspector& inspector) char format_string[5]; AP4_FormatFourChars(format_string, m_DescriptionFormat); inspector.AddField("description_format", format_string); - inspector.AddField("sdp_text", m_SdpText.c_str()); + inspector.AddField("sdp_text", m_SdpText.GetChars()); return AP4_SUCCESS; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpAtom.h index 1ae414f60..596d96cfc 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpAtom.h @@ -2,7 +2,7 @@ | | AP4 - rtp Atoms | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,27 +30,38 @@ #define _AP4_RTP_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" +#include "Ap4Types.h" #include "Ap4List.h" +#include "Ap4String.h" #include "Ap4Atom.h" -#include "Ap4DataBuffer.h" /*---------------------------------------------------------------------- -| AP4_RtpAtom +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| AP4_RtpAtom +---------------------------------------------------------------------*/ class AP4_RtpAtom : public AP4_Atom { public: + // class methods + static AP4_RtpAtom* Create(AP4_Size size, AP4_ByteStream& stream) { + return new AP4_RtpAtom(size, stream); + } + // methods - AP4_RtpAtom(AP4_Size size, AP4_ByteStream& stream); const AP4_String& GetSdpText() { return m_SdpText; } virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); private: + // methods + AP4_RtpAtom(AP4_UI32 size, AP4_ByteStream& stream); + // members AP4_UI32 m_DescriptionFormat; AP4_String m_SdpText; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpHint.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpHint.cpp index 111ce13cb..3f9f19c0e 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpHint.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpHint.cpp @@ -2,7 +2,7 @@ | | AP4 - RTP Hint Objects | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -26,14 +26,14 @@ | ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4RtpHint.h" #include "Ap4ByteStream.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_RtpSampleData::~AP4_RtpSampleData +| AP4_RtpSampleData::~AP4_RtpSampleData +---------------------------------------------------------------------*/ AP4_RtpSampleData::~AP4_RtpSampleData() { @@ -45,12 +45,12 @@ AP4_RtpSampleData::~AP4_RtpSampleData() } /*---------------------------------------------------------------------- -| AP4_RtpSampleData::AP4_RtpSampleData +| AP4_RtpSampleData::AP4_RtpSampleData +---------------------------------------------------------------------*/ -AP4_RtpSampleData::AP4_RtpSampleData(AP4_ByteStream& stream, AP4_Size size) +AP4_RtpSampleData::AP4_RtpSampleData(AP4_ByteStream& stream, AP4_UI32 size) { // save the start position - AP4_Offset start, extra_data_start; + AP4_Position start, extra_data_start; stream.Tell(start); AP4_UI16 packet_count; @@ -61,13 +61,13 @@ AP4_RtpSampleData::AP4_RtpSampleData(AP4_ByteStream& stream, AP4_Size size) // packets for (AP4_UI16 i=0; i<packet_count; i++) { - AP4_RtpPacket* packet = DNew AP4_RtpPacket(stream); + AP4_RtpPacket* packet = new AP4_RtpPacket(stream); m_Packets.Add(packet); } // extra data stream.Tell(extra_data_start); - AP4_Size extra_data_size = size - (extra_data_start-start); + AP4_Size extra_data_size = size - (AP4_UI32)(extra_data_start-start); if (extra_data_size != 0) { m_ExtraData.SetDataSize(extra_data_size); stream.Read(m_ExtraData.UseData(), extra_data_size); @@ -75,7 +75,7 @@ AP4_RtpSampleData::AP4_RtpSampleData(AP4_ByteStream& stream, AP4_Size size) } /*---------------------------------------------------------------------- -| AP4_RtpSampleData::GetSize +| AP4_RtpSampleData::GetSize +---------------------------------------------------------------------*/ AP4_Size AP4_RtpSampleData::GetSize() @@ -97,7 +97,7 @@ AP4_RtpSampleData::GetSize() } /*---------------------------------------------------------------------- -| AP4_RtpSampleData::ToByteStream +| AP4_RtpSampleData::ToByteStream +---------------------------------------------------------------------*/ AP4_ByteStream* AP4_RtpSampleData::ToByteStream() @@ -106,7 +106,7 @@ AP4_RtpSampleData::ToByteStream() AP4_Size size = GetSize(); // create a memory stream - AP4_MemoryByteStream* stream = DNew AP4_MemoryByteStream(size); + AP4_MemoryByteStream* stream = new AP4_MemoryByteStream(size); // write in it AP4_Result result = stream->WriteUI16(static_cast<AP4_UI16>(m_Packets.ItemCount())); @@ -116,13 +116,13 @@ AP4_RtpSampleData::ToByteStream() if (AP4_FAILED(result)) goto bail; { - AP4_List<AP4_RtpPacket>::Item* it = m_Packets.FirstItem(); - while (it != NULL) { - result = it->GetData()->Write(*stream); - if (AP4_FAILED(result)) goto bail; - it = it->GetNext(); - } - } + AP4_List<AP4_RtpPacket>::Item* it = m_Packets.FirstItem(); + while (it != NULL) { + result = it->GetData()->Write(*stream); + if (AP4_FAILED(result)) goto bail; + it = it->GetNext(); + } + } result = stream->Write(m_ExtraData.GetData(), m_ExtraData.GetDataSize()); if (AP4_FAILED(result)) goto bail; @@ -137,7 +137,7 @@ bail: /*---------------------------------------------------------------------- -| AP4_RtpSampleData::AddPacket +| AP4_RtpSampleData::AddPacket +---------------------------------------------------------------------*/ AP4_Result AP4_RtpSampleData::AddPacket(AP4_RtpPacket* packet) @@ -147,17 +147,17 @@ AP4_RtpSampleData::AddPacket(AP4_RtpPacket* packet) } /*---------------------------------------------------------------------- -| AP4_RtpPacket::AP4_RtpPacket +| AP4_RtpPacket::AP4_RtpPacket +---------------------------------------------------------------------*/ -AP4_RtpPacket::AP4_RtpPacket(AP4_Integer relative_time, - bool p_bit, - bool x_bit, - bool m_bit, +AP4_RtpPacket::AP4_RtpPacket(int relative_time, + bool p_bit, + bool x_bit, + bool m_bit, AP4_UI08 payload_type, AP4_UI16 sequence_seed, - AP4_Integer time_stamp_offset /* = 0 */, - bool bframe_flag /* = false */, - bool repeat_flag /* = false */) : + int time_stamp_offset /* = 0 */, + bool bframe_flag /* = false */, + bool repeat_flag /* = false */) : m_ReferenceCount(1), m_RelativeTime(relative_time), m_PBit(p_bit), @@ -171,7 +171,7 @@ AP4_RtpPacket::AP4_RtpPacket(AP4_Integer relative_time, {} /*---------------------------------------------------------------------- -| AP4_RtpPacket::AP4_RtpPacket +| AP4_RtpPacket::AP4_RtpPacket +---------------------------------------------------------------------*/ AP4_RtpPacket::AP4_RtpPacket(AP4_ByteStream& stream) : m_ReferenceCount(1), @@ -217,8 +217,7 @@ AP4_RtpPacket::AP4_RtpPacket(AP4_ByteStream& stream) : stream.ReadUI32(extra_length); // check it - if (extra_length < 4) - throw AP4_Exception(AP4_ERROR_INVALID_RTP_PACKET_EXTRA_DATA); + if (extra_length < 4) return; // now read the entries extra_length -= 4; @@ -229,9 +228,7 @@ AP4_RtpPacket::AP4_RtpPacket(AP4_ByteStream& stream) : stream.ReadUI32(entry_tag); // check the entry - if (entry_length < 8) { - throw AP4_Exception(AP4_ERROR_INVALID_RTP_PACKET_EXTRA_DATA); - } + if (entry_length < 8) return; // parse the single entry that's currently defined in the spec if (entry_tag == AP4_ATOM_TYPE('r','t','p','o') && entry_length == 12) { @@ -240,7 +237,7 @@ AP4_RtpPacket::AP4_RtpPacket(AP4_ByteStream& stream) : m_TimeStampOffset = time_stamp_offset; } else { // ignore it - AP4_Offset cur_pos; + AP4_Position cur_pos; stream.Tell(cur_pos); stream.Seek(cur_pos + entry_length - 8); // 8 = length + tag } @@ -258,7 +255,7 @@ AP4_RtpPacket::AP4_RtpPacket(AP4_ByteStream& stream) : } /*---------------------------------------------------------------------- -| AP4_RtpPacket::AP4_RtpPacket +| AP4_RtpPacket::AP4_RtpPacket +---------------------------------------------------------------------*/ AP4_RtpPacket::~AP4_RtpPacket() { @@ -270,7 +267,7 @@ AP4_RtpPacket::~AP4_RtpPacket() } /*---------------------------------------------------------------------- -| AP4_RtpPacket::AddReference +| AP4_RtpPacket::AddReference +---------------------------------------------------------------------*/ void AP4_RtpPacket::AddReference() @@ -279,7 +276,7 @@ AP4_RtpPacket::AddReference() } /*---------------------------------------------------------------------- -| AP4_RtpPacket::Release +| AP4_RtpPacket::Release +---------------------------------------------------------------------*/ void AP4_RtpPacket::Release() @@ -290,7 +287,7 @@ AP4_RtpPacket::Release() } /*---------------------------------------------------------------------- -| AP4_RtpPacket::GetSize +| AP4_RtpPacket::GetSize +---------------------------------------------------------------------*/ AP4_Size AP4_RtpPacket::GetSize() @@ -301,7 +298,7 @@ AP4_RtpPacket::GetSize() } /*---------------------------------------------------------------------- -| AP4_RtpPacket::Write +| AP4_RtpPacket::Write +---------------------------------------------------------------------*/ AP4_Result AP4_RtpPacket::Write(AP4_ByteStream& stream) @@ -362,7 +359,7 @@ AP4_RtpPacket::Write(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_RtpPacket::AddConstructor +| AP4_RtpPacket::AddConstructor +---------------------------------------------------------------------*/ AP4_Result AP4_RtpPacket::AddConstructor(AP4_RtpConstructor* constructor) @@ -372,7 +369,7 @@ AP4_RtpPacket::AddConstructor(AP4_RtpConstructor* constructor) } /*---------------------------------------------------------------------- -| AP4_RtpConstructor::GetConstructedDataSize +| AP4_RtpConstructor::GetConstructedDataSize +---------------------------------------------------------------------*/ AP4_Size AP4_RtpPacket::GetConstructedDataSize() @@ -393,7 +390,7 @@ AP4_RtpPacket::GetConstructedDataSize() /*---------------------------------------------------------------------- -| AP4_RtpConstructor::AddReference +| AP4_RtpConstructor::AddReference +---------------------------------------------------------------------*/ void AP4_RtpConstructor::AddReference() @@ -402,7 +399,7 @@ AP4_RtpConstructor::AddReference() } /*---------------------------------------------------------------------- -| AP4_RtpConstructor::Release +| AP4_RtpConstructor::Release +---------------------------------------------------------------------*/ void AP4_RtpConstructor::Release() @@ -412,7 +409,7 @@ AP4_RtpConstructor::Release() } } /*---------------------------------------------------------------------- -| AP4_RtpConstructor::Write +| AP4_RtpConstructor::Write +---------------------------------------------------------------------*/ AP4_Result AP4_RtpConstructor::Write(AP4_ByteStream& stream) @@ -424,18 +421,18 @@ AP4_RtpConstructor::Write(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_NoopRtpConstructor::AP4_NoopRtpConstructor +| AP4_NoopRtpConstructor::AP4_NoopRtpConstructor +---------------------------------------------------------------------*/ AP4_NoopRtpConstructor::AP4_NoopRtpConstructor(AP4_ByteStream& stream) : AP4_RtpConstructor(AP4_RTP_CONSTRUCTOR_TYPE_NOOP) { - AP4_Offset cur_offset; + AP4_Position cur_offset; stream.Tell(cur_offset); stream.Seek(cur_offset+15); } /*---------------------------------------------------------------------- -| AP4_NoopRtpConstructor::DoWrite +| AP4_NoopRtpConstructor::DoWrite +---------------------------------------------------------------------*/ AP4_Result AP4_NoopRtpConstructor::DoWrite(AP4_ByteStream& stream) @@ -446,7 +443,7 @@ AP4_NoopRtpConstructor::DoWrite(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_ImmediateRtpConstructor::AP4_ImmediateRtpConstructor +| AP4_ImmediateRtpConstructor::AP4_ImmediateRtpConstructor +---------------------------------------------------------------------*/ AP4_ImmediateRtpConstructor::AP4_ImmediateRtpConstructor(const AP4_DataBuffer& data) : AP4_RtpConstructor(AP4_RTP_CONSTRUCTOR_TYPE_IMMEDIATE), @@ -454,12 +451,12 @@ AP4_ImmediateRtpConstructor::AP4_ImmediateRtpConstructor(const AP4_DataBuffer& d {} /*---------------------------------------------------------------------- -| AP4_ImmediateRtpConstructor::AP4_ImmediateRtpConstructor +| AP4_ImmediateRtpConstructor::AP4_ImmediateRtpConstructor +---------------------------------------------------------------------*/ AP4_ImmediateRtpConstructor::AP4_ImmediateRtpConstructor(AP4_ByteStream& stream) : AP4_RtpConstructor(AP4_RTP_CONSTRUCTOR_TYPE_IMMEDIATE) { - AP4_Offset cur_offset; + AP4_Position cur_offset; stream.Tell(cur_offset); // data @@ -474,7 +471,7 @@ AP4_ImmediateRtpConstructor::AP4_ImmediateRtpConstructor(AP4_ByteStream& stream) /*---------------------------------------------------------------------- -| AP4_ImmediateRtpConstructor::DoWrite +| AP4_ImmediateRtpConstructor::DoWrite +---------------------------------------------------------------------*/ AP4_Result AP4_ImmediateRtpConstructor::DoWrite(AP4_ByteStream& stream) @@ -494,7 +491,7 @@ AP4_ImmediateRtpConstructor::DoWrite(AP4_ByteStream& stream) return stream.Write(pad, sizeof(pad)-m_Data.GetDataSize()); } /*---------------------------------------------------------------------- -| AP4_SampleRtpConstructor::AP4_SampleRtpConstructor +| AP4_SampleRtpConstructor::AP4_SampleRtpConstructor +---------------------------------------------------------------------*/ AP4_SampleRtpConstructor::AP4_SampleRtpConstructor(AP4_UI08 track_ref_index, AP4_UI16 length, @@ -508,13 +505,13 @@ AP4_SampleRtpConstructor::AP4_SampleRtpConstructor(AP4_UI08 track_ref_index, {} /*---------------------------------------------------------------------- -| AP4_SampleRtpConstructor::AP4_SampleRtpConstructor +| AP4_SampleRtpConstructor::AP4_SampleRtpConstructor +---------------------------------------------------------------------*/ AP4_SampleRtpConstructor::AP4_SampleRtpConstructor(AP4_ByteStream& stream) : AP4_RtpConstructor(AP4_RTP_CONSTRUCTOR_TYPE_SAMPLE) { // offset - AP4_Offset cur_offset; + AP4_Position cur_offset; stream.Tell(cur_offset); // data @@ -527,7 +524,7 @@ AP4_SampleRtpConstructor::AP4_SampleRtpConstructor(AP4_ByteStream& stream) : stream.Seek(cur_offset+15); } /*---------------------------------------------------------------------- -| AP4_SampleRtpConstructor::DoWrite +| AP4_SampleRtpConstructor::DoWrite +---------------------------------------------------------------------*/ AP4_Result AP4_SampleRtpConstructor::DoWrite(AP4_ByteStream& stream) @@ -551,7 +548,7 @@ AP4_SampleRtpConstructor::DoWrite(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_SampleDescRtpConstructor::AP4_SampleDescRtpConstructor +| AP4_SampleDescRtpConstructor::AP4_SampleDescRtpConstructor +---------------------------------------------------------------------*/ AP4_SampleDescRtpConstructor::AP4_SampleDescRtpConstructor(AP4_UI08 track_ref_index, AP4_UI16 length, @@ -565,13 +562,13 @@ AP4_SampleDescRtpConstructor::AP4_SampleDescRtpConstructor(AP4_UI08 track_ref_in {} /*---------------------------------------------------------------------- -| AP4_SampleDescRtpConstructor::AP4_SampleDescRtpConstructor +| AP4_SampleDescRtpConstructor::AP4_SampleDescRtpConstructor +---------------------------------------------------------------------*/ AP4_SampleDescRtpConstructor::AP4_SampleDescRtpConstructor(AP4_ByteStream& stream) : AP4_RtpConstructor(AP4_RTP_CONSTRUCTOR_TYPE_SAMPLE_DESC) { // offset - AP4_Offset cur_offset; + AP4_Position cur_offset; stream.Tell(cur_offset); // data @@ -585,7 +582,7 @@ AP4_SampleDescRtpConstructor::AP4_SampleDescRtpConstructor(AP4_ByteStream& strea } /*---------------------------------------------------------------------- -| AP4_SampleDescRtpConstructor::DoWrite +| AP4_SampleDescRtpConstructor::DoWrite +---------------------------------------------------------------------*/ AP4_Result AP4_SampleDescRtpConstructor::DoWrite(AP4_ByteStream& stream) @@ -606,7 +603,7 @@ AP4_SampleDescRtpConstructor::DoWrite(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_RtpConstructorFactory::CreateConstructorFromStream +| AP4_RtpConstructorFactory::CreateConstructorFromStream +---------------------------------------------------------------------*/ AP4_Result AP4_RtpConstructorFactory::CreateConstructorFromStream(AP4_ByteStream& stream, @@ -617,18 +614,19 @@ AP4_RtpConstructorFactory::CreateConstructorFromStream(AP4_ByteStream& stream, AP4_Result result = stream.ReadUI08(type); if (AP4_FAILED(result)) return result; + // now create the right constructor switch(type) { case AP4_RTP_CONSTRUCTOR_TYPE_NOOP: - constructor = DNew AP4_NoopRtpConstructor(stream); + constructor = new AP4_NoopRtpConstructor(stream); break; case AP4_RTP_CONSTRUCTOR_TYPE_IMMEDIATE: - constructor = DNew AP4_ImmediateRtpConstructor(stream); + constructor = new AP4_ImmediateRtpConstructor(stream); break; case AP4_RTP_CONSTRUCTOR_TYPE_SAMPLE: - constructor = DNew AP4_SampleRtpConstructor(stream); + constructor = new AP4_SampleRtpConstructor(stream); break; case AP4_RTP_CONSTRUCTOR_TYPE_SAMPLE_DESC: - constructor = DNew AP4_SampleDescRtpConstructor(stream); + constructor = new AP4_SampleDescRtpConstructor(stream); break; default: return AP4_ERROR_INVALID_RTP_CONSTRUCTOR_TYPE; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpHint.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpHint.h index b5cfd67f1..f747c8212 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpHint.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4RtpHint.h @@ -2,7 +2,7 @@ | | AP4 - RTP Hint Objects | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,28 +30,28 @@ #define _AP4_RTP_HINT_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" +#include "Ap4Types.h" #include "Ap4List.h" #include "Ap4DataBuffer.h" #include "Ap4Interfaces.h" /*---------------------------------------------------------------------- -| forward declarations +| forward declarations +---------------------------------------------------------------------*/ class AP4_ByteStream; class AP4_RtpConstructor; class AP4_RtpPacket; /*---------------------------------------------------------------------- -| AP4_RtpSampleData +| AP4_RtpSampleData +---------------------------------------------------------------------*/ class AP4_RtpSampleData { public: // constructors and destructor - AP4_RtpSampleData(AP4_ByteStream& stream, AP4_Size size); + AP4_RtpSampleData(AP4_ByteStream& stream, AP4_UI32 size); AP4_RtpSampleData() {} virtual ~AP4_RtpSampleData(); @@ -75,22 +75,22 @@ protected: }; /*---------------------------------------------------------------------- -| AP4_RtpPacket +| AP4_RtpPacket +---------------------------------------------------------------------*/ class AP4_RtpPacket : public AP4_Referenceable { public: // constructor and destructor AP4_RtpPacket(AP4_ByteStream& stream); - AP4_RtpPacket(AP4_Integer relative_time, - bool p_bit, - bool x_bit, - bool m_bit, + AP4_RtpPacket(int relative_time, + bool p_bit, + bool x_bit, + bool m_bit, AP4_UI08 payload_type, AP4_UI16 sequence_seed, - AP4_Integer time_stamp_offset = 0, - bool bframe_flag = false, - bool repeat_flag = false); + int time_stamp_offset = 0, + bool bframe_flag = false, + bool repeat_flag = false); ~AP4_RtpPacket(); // methods @@ -104,13 +104,13 @@ public: void Release(); // Accessors - AP4_Integer GetRelativeTime() const { return m_RelativeTime; } + int GetRelativeTime() const { return m_RelativeTime; } bool GetPBit() const { return m_PBit; } bool GetXBit() const { return m_XBit; } bool GetMBit() const { return m_MBit; } AP4_UI08 GetPayloadType() const { return m_PayloadType; } AP4_UI16 GetSequenceSeed() const { return m_SequenceSeed; } - AP4_Integer GetTimeStampOffset() const { return m_TimeStampOffset; } + int GetTimeStampOffset() const { return m_TimeStampOffset; } bool GetBFrameFlag() const { return m_BFrameFlag; } bool GetRepeatFlag() const { return m_RepeatFlag; } AP4_List<AP4_RtpConstructor>& GetConstructors() { @@ -120,20 +120,20 @@ public: private: // members AP4_Cardinal m_ReferenceCount; - AP4_Integer m_RelativeTime; + int m_RelativeTime; bool m_PBit; bool m_XBit; bool m_MBit; AP4_UI08 m_PayloadType; AP4_UI16 m_SequenceSeed; - AP4_Integer m_TimeStampOffset; + int m_TimeStampOffset; bool m_BFrameFlag; bool m_RepeatFlag; AP4_List<AP4_RtpConstructor> m_Constructors; }; /*---------------------------------------------------------------------- -| AP4_RtpContructor +| AP4_RtpContructor +---------------------------------------------------------------------*/ class AP4_RtpConstructor : public AP4_Referenceable { @@ -164,12 +164,12 @@ protected: }; /*---------------------------------------------------------------------- -| constructor size +| constructor size +---------------------------------------------------------------------*/ const AP4_Size AP4_RTP_CONSTRUCTOR_SIZE = 16; /*---------------------------------------------------------------------- -| constructor types +| constructor types +---------------------------------------------------------------------*/ const AP4_RtpConstructor::Type AP4_RTP_CONSTRUCTOR_TYPE_NOOP = 0; const AP4_RtpConstructor::Type AP4_RTP_CONSTRUCTOR_TYPE_IMMEDIATE = 1; @@ -177,7 +177,7 @@ const AP4_RtpConstructor::Type AP4_RTP_CONSTRUCTOR_TYPE_SAMPLE = 2; const AP4_RtpConstructor::Type AP4_RTP_CONSTRUCTOR_TYPE_SAMPLE_DESC = 3; /*---------------------------------------------------------------------- -| AP4_NoopRtpConstructor +| AP4_NoopRtpConstructor +---------------------------------------------------------------------*/ class AP4_NoopRtpConstructor : public AP4_RtpConstructor { @@ -195,7 +195,7 @@ protected: }; /*---------------------------------------------------------------------- -| AP4_ImmediateRtpConstructor +| AP4_ImmediateRtpConstructor +---------------------------------------------------------------------*/ class AP4_ImmediateRtpConstructor : public AP4_RtpConstructor { @@ -219,7 +219,7 @@ protected: }; /*---------------------------------------------------------------------- -| AP4_SampleRtpConstructor +| AP4_SampleRtpConstructor +---------------------------------------------------------------------*/ class AP4_SampleRtpConstructor : public AP4_RtpConstructor { @@ -252,7 +252,7 @@ protected: }; /*---------------------------------------------------------------------- -| AP4_SampleDescRtpConstructor +| AP4_SampleDescRtpConstructor +---------------------------------------------------------------------*/ class AP4_SampleDescRtpConstructor : public AP4_RtpConstructor { @@ -285,12 +285,12 @@ protected: }; /*---------------------------------------------------------------------- -| AP4_RtpConstructorFactory +| AP4_RtpConstructorFactory +---------------------------------------------------------------------*/ class AP4_RtpConstructorFactory { public: - static AP4_Result CreateConstructorFromStream(AP4_ByteStream& stream, + static AP4_Result CreateConstructorFromStream(AP4_ByteStream& stream, AP4_RtpConstructor*& constructor); }; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SLConfigDescriptor.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SLConfigDescriptor.cpp index e15821f8e..7b791c3e4 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SLConfigDescriptor.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SLConfigDescriptor.cpp @@ -2,7 +2,7 @@ | | AP4 - SLConfig Descriptor | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,22 +27,22 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4SLConfigDescriptor.h" +#include "Ap4ByteStream.h" /*---------------------------------------------------------------------- -| AP4_SLConfigDescriptor::AP4_SLConfigDescriptor +| AP4_SLConfigDescriptor::AP4_SLConfigDescriptor +---------------------------------------------------------------------*/ -AP4_SLConfigDescriptor::AP4_SLConfigDescriptor(AP4_Size header_size = 2) : +AP4_SLConfigDescriptor::AP4_SLConfigDescriptor(AP4_Size header_size) : AP4_Descriptor(AP4_DESCRIPTOR_TAG_SL_CONFIG, header_size, 1), m_Predefined(2) { } /*---------------------------------------------------------------------- -| AP4_SLConfigDescriptor::WriteFields +| AP4_SLConfigDescriptor::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_SLConfigDescriptor::WriteFields(AP4_ByteStream& stream) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SLConfigDescriptor.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SLConfigDescriptor.h index 19026b081..73a26ec9b 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SLConfigDescriptor.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SLConfigDescriptor.h @@ -2,7 +2,7 @@ | | AP4 - SLConfig Descriptor | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,27 +30,24 @@ #define _AP4_SLCONFIG_DESCRIPTOR_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4List.h" -#include "Ap4DataBuffer.h" +#include "Ap4Types.h" #include "Ap4Descriptor.h" /*---------------------------------------------------------------------- -| constants +| constants +---------------------------------------------------------------------*/ -const AP4_Descriptor::Tag AP4_DESCRIPTOR_TAG_SL_CONFIG = 0x06; +const AP4_UI08 AP4_DESCRIPTOR_TAG_SL_CONFIG = 0x06; /*---------------------------------------------------------------------- -| AP4_SLConfigDescriptor +| AP4_SLConfigDescriptor +---------------------------------------------------------------------*/ class AP4_SLConfigDescriptor : public AP4_Descriptor { public: // methods - AP4_SLConfigDescriptor(AP4_Size header_size); + AP4_SLConfigDescriptor(AP4_Size header_size = 2); virtual AP4_Result WriteFields(AP4_ByteStream& stream); private: diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Sample.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Sample.cpp index 9424e5982..060084044 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Sample.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Sample.cpp @@ -1,160 +1,175 @@ -/*****************************************************************
-|
-| AP4 - Sample Objects
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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 "Ap4Sample.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_Sample::AP4_Sample
-+---------------------------------------------------------------------*/
-AP4_Sample::AP4_Sample() :
- m_DataStream(NULL),
- m_Offset(0),
- m_Size(0),
- m_DescriptionIndex(0),
- m_Dts(0),
- m_Cts(0)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_Sample::AP4_Sample
-+---------------------------------------------------------------------*/
-AP4_Sample::AP4_Sample(AP4_ByteStream& data_stream,
- AP4_Offset offset,
- AP4_Size size,
- AP4_Ordinal description_index,
- AP4_TimeStamp dts,
- AP4_TimeStamp cts_offset /* = 0 */ ) :
- m_Offset(offset),
- m_Size(size),
- m_DescriptionIndex(description_index),
- m_Dts(dts),
- m_Cts(dts + cts_offset)
-{
- m_DataStream = &data_stream;
- AP4_ADD_REFERENCE(m_DataStream);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Sample::AP4_Sample
-+---------------------------------------------------------------------*/
-AP4_Sample::AP4_Sample(const AP4_Sample& other) :
- m_DataStream(other.m_DataStream),
- m_Offset(other.m_Offset),
- m_Size(other.m_Size),
- m_DescriptionIndex(other.m_DescriptionIndex),
- m_Dts(other.m_Dts),
- m_Cts(other.m_Cts)
-{
- AP4_ADD_REFERENCE(m_DataStream);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Sample::~AP4_Sample
-+---------------------------------------------------------------------*/
-AP4_Sample::~AP4_Sample()
-{
- AP4_RELEASE(m_DataStream);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Sample::operator=
-+---------------------------------------------------------------------*/
-AP4_Sample&
-AP4_Sample::operator=(const AP4_Sample& other)
-{
- AP4_RELEASE(m_DataStream);
- m_DataStream = other.m_DataStream;
- AP4_ADD_REFERENCE(m_DataStream);
-
- m_Offset = other.m_Offset;
- m_Size = other.m_Size;
- m_DescriptionIndex = other.m_DescriptionIndex;
- m_Dts = other.m_Dts;
- m_Cts = other.m_Cts;
-
- return *this;
-}
-/*----------------------------------------------------------------------
-| AP4_Sample::ReadData
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Sample::ReadData(AP4_DataBuffer& data)
-{
- return ReadData(data, m_Size);
-}
-
-
-/*----------------------------------------------------------------------
-| AP4_Sample::ReadData
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Sample::ReadData(AP4_DataBuffer& data, AP4_Size size, AP4_Offset offset)
-{
- // check that we have a stream
- if (m_DataStream == NULL) return AP4_FAILURE;
-
- // shortcut
- if (size == 0) return AP4_SUCCESS;
-
- // check the size
- if (m_Size < size+offset) return AP4_FAILURE;
-
- // set the buffer size
- AP4_Result result = data.SetDataSize(size);
- if (AP4_FAILED(result)) return result;
-
- // get the data from the stream
- m_DataStream->Seek(m_Offset+offset);
- return m_DataStream->Read(data.UseData(), size);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Sample::GetDataStream
-+---------------------------------------------------------------------*/
-AP4_ByteStream*
-AP4_Sample::GetDataStream()
-{
- AP4_ADD_REFERENCE(m_DataStream);
- return m_DataStream;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Sample::SetDataStream
-+---------------------------------------------------------------------*/
-void
-AP4_Sample::SetDataStream(AP4_ByteStream& stream)
-{
- AP4_RELEASE(m_DataStream);
- m_DataStream = &stream;
- AP4_ADD_REFERENCE(m_DataStream);
-}
+/***************************************************************** +| +| AP4 - Sample Objects +| +| 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 "Ap4Sample.h" +#include "Ap4Utils.h" +#include "Ap4DataBuffer.h" +#include "Ap4Interfaces.h" +#include "Ap4ByteStream.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_Sample::AP4_Sample ++---------------------------------------------------------------------*/ +AP4_Sample::AP4_Sample() : + m_DataStream(NULL), + m_Offset(0), + m_Size(0), + m_Duration(0), + m_DescriptionIndex(0), + m_Dts(0), + m_CtsDelta(0), + m_IsSync(true) +{ +} + +/*---------------------------------------------------------------------- +| AP4_Sample::AP4_Sample ++---------------------------------------------------------------------*/ +AP4_Sample::AP4_Sample(AP4_ByteStream& data_stream, + AP4_Position offset, + AP4_Size size, + AP4_UI32 duration, + AP4_Ordinal description_index, + AP4_UI64 dts, + AP4_UI32 cts_delta, + bool is_sync) : + m_Offset(offset), + m_Size(size), + m_Duration(duration), + m_DescriptionIndex(description_index), + m_Dts(dts), + m_CtsDelta(cts_delta), + m_IsSync(is_sync) +{ + m_DataStream = &data_stream; + AP4_ADD_REFERENCE(m_DataStream); +} + +/*---------------------------------------------------------------------- +| AP4_Sample::AP4_Sample ++---------------------------------------------------------------------*/ +AP4_Sample::AP4_Sample(const AP4_Sample& other) : + m_DataStream(other.m_DataStream), + m_Offset(other.m_Offset), + m_Size(other.m_Size), + m_Duration(other.m_Duration), + m_DescriptionIndex(other.m_DescriptionIndex), + m_Dts(other.m_Dts), + m_CtsDelta(other.m_CtsDelta), + m_IsSync(other.m_IsSync) +{ + AP4_ADD_REFERENCE(m_DataStream); +} + +/*---------------------------------------------------------------------- +| AP4_Sample::~AP4_Sample ++---------------------------------------------------------------------*/ +AP4_Sample::~AP4_Sample() +{ + AP4_RELEASE(m_DataStream); +} + +/*---------------------------------------------------------------------- +| AP4_Sample::operator= ++---------------------------------------------------------------------*/ +AP4_Sample& +AP4_Sample::operator=(const AP4_Sample& other) +{ + AP4_ADD_REFERENCE(other.m_DataStream); + AP4_RELEASE(m_DataStream); + m_DataStream = other.m_DataStream; + + m_Offset = other.m_Offset; + m_Size = other.m_Size; + m_Duration = other.m_Duration; + m_DescriptionIndex = other.m_DescriptionIndex; + m_Dts = other.m_Dts; + m_CtsDelta = other.m_CtsDelta; + m_IsSync = other.m_IsSync; + + return *this; +} +/*---------------------------------------------------------------------- +| AP4_Sample::ReadData ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Sample::ReadData(AP4_DataBuffer& data) +{ + return ReadData(data, m_Size); +} + + +/*---------------------------------------------------------------------- +| AP4_Sample::ReadData ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Sample::ReadData(AP4_DataBuffer& data, AP4_Size size, AP4_Size offset) +{ + // check that we have a stream + if (m_DataStream == NULL) return AP4_FAILURE; + + // shortcut + if (size == 0) return AP4_SUCCESS; + + // check the size + if (m_Size < size+offset) return AP4_FAILURE; + + // set the buffer size + AP4_Result result = data.SetDataSize(size); + if (AP4_FAILED(result)) return result; + + // get the data from the stream + result = m_DataStream->Seek(m_Offset+offset); + if (AP4_FAILED(result)) return result; + return m_DataStream->Read(data.UseData(), size); +} + +/*---------------------------------------------------------------------- +| AP4_Sample::GetDataStream ++---------------------------------------------------------------------*/ +AP4_ByteStream* +AP4_Sample::GetDataStream() +{ + AP4_ADD_REFERENCE(m_DataStream); + return m_DataStream; +} + +/*---------------------------------------------------------------------- +| AP4_Sample::SetDataStream ++---------------------------------------------------------------------*/ +void +AP4_Sample::SetDataStream(AP4_ByteStream& stream) +{ + AP4_RELEASE(m_DataStream); + m_DataStream = &stream; + AP4_ADD_REFERENCE(m_DataStream); +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Sample.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Sample.h index 184499f70..60a9e345c 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Sample.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Sample.h @@ -1,91 +1,168 @@ -/*****************************************************************
-|
-| AP4 - Sample Objects
-|
-| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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_SAMPLE_H_
-#define _AP4_SAMPLE_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4DataBuffer.h"
-
-/*----------------------------------------------------------------------
-| AP4_Sample DO NOT DERIVE FROM THIS CLASS
-+---------------------------------------------------------------------*/
-class AP4_Sample
-{
-public:
- // constructors and destructor
- AP4_Sample();
- AP4_Sample(const AP4_Sample& other);
- AP4_Sample(AP4_ByteStream& data_stream,
- AP4_Offset offset,
- AP4_Size size,
- AP4_Ordinal description_index,
- AP4_TimeStamp dts,
- AP4_TimeStamp cts_offset = 0);
- ~AP4_Sample(); // not virtual on purpose: do not derive from it
-
- // operators
- AP4_Sample& operator=(const AP4_Sample& other);
-
- // methods
- AP4_Result ReadData(AP4_DataBuffer& data);
- AP4_Result ReadData(AP4_DataBuffer& data,
- AP4_Size size,
- AP4_Offset offset = 0);
-
- // sample properties accessors
- AP4_ByteStream* GetDataStream();
- void SetDataStream(AP4_ByteStream& stream);
- AP4_Offset GetOffset() const { return m_Offset; }
- void SetOffset(AP4_Offset offset) { m_Offset = offset; }
- AP4_Size GetSize() { return m_Size; }
- void SetSize(AP4_Size size) { m_Size = size; }
- AP4_Ordinal GetDescriptionIndex() const { return m_DescriptionIndex; }
- void SetDescriptionIndex(AP4_Ordinal index) { m_DescriptionIndex = index; }
- AP4_TimeStamp GetDts() const { return m_Dts; }
- void SetDts(AP4_TimeStamp dts) { m_Dts = dts; }
- AP4_TimeStamp GetDuration() const { return m_Duration; }
- void SetDuration(AP4_Duration duration) { m_Duration = duration;}
- AP4_TimeStamp GetCts() const { return m_Cts; }
- void SetCts(AP4_TimeStamp cts) { m_Cts = cts; }
-
-protected:
- AP4_ByteStream* m_DataStream;
- AP4_Offset m_Offset;
- AP4_Size m_Size;
- AP4_Ordinal m_DescriptionIndex;
- AP4_TimeStamp m_Dts;
- AP4_TimeStamp m_Cts;
- AP4_Duration m_Duration;
-};
-
-#endif // _AP4_SAMPLE_H_
+/***************************************************************** +| +| AP4 - Sample Objects +| +| 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_SAMPLE_H_ +#define _AP4_SAMPLE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; +class AP4_DataBuffer; + +/*---------------------------------------------------------------------- +| AP4_Sample DO NOT DERIVE FROM THIS CLASS ++---------------------------------------------------------------------*/ +class AP4_Sample +{ +public: + /** + * Default constructor + */ + AP4_Sample(); + + /** + * Copy constructor + */ + AP4_Sample(const AP4_Sample& other); + + /** + * Construct an AP4_Sample referencing a data stream + * + * @param data_stream The byte stream that contains the sample data. + * The sample object added to the track will keep a reference to that byte + * stream + * @param offset Position of the first byte of sample data within the stream + * @param size Size in bytes of the sample data + * @param description_index Index of the sample description that applies to + * this sample + * @param dts Decoding timestamp of the sample + * @param cts_delta Difference between the CTS (composition/display timestamp) and the + * DTS (decoding timestamp), in the timescale of the media. + * @param sync_flag Boolean flag indicating whether this is a sync sample + * or not + */ + AP4_Sample(AP4_ByteStream& data_stream, + AP4_Position offset, + AP4_Size size, + AP4_UI32 duration, + AP4_Ordinal description_index, + AP4_UI64 dts, + AP4_UI32 cts_delta, + bool sync_flag); + + ~AP4_Sample(); // not virtual on purpose: do not derive from it + + // operators + AP4_Sample& operator=(const AP4_Sample& other); + + // methods + AP4_Result ReadData(AP4_DataBuffer& data); + AP4_Result ReadData(AP4_DataBuffer& data, + AP4_Size size, + AP4_Size offset = 0); + + // sample properties accessors + AP4_ByteStream* GetDataStream(); + void SetDataStream(AP4_ByteStream& stream); + AP4_Position GetOffset() const { return m_Offset; } + void SetOffset(AP4_Position offset) { m_Offset = offset; } + AP4_Size GetSize() { return m_Size; } + void SetSize(AP4_Size size) { m_Size = size; } + AP4_Ordinal GetDescriptionIndex() const { return m_DescriptionIndex; } + void SetDescriptionIndex(AP4_Ordinal index) { m_DescriptionIndex = index; } + + /** + * Get the DTS (Decoding Time Stamp) of the sample in the timescale of the media + */ + AP4_UI64 GetDts() const { return m_Dts; } + + /** + * Set the DTS (Decoding Time Stamp) of the sample in the timescale of the media + */ + void SetDts(AP4_UI64 dts) { m_Dts = dts; } + + /** + * Get the CTS (Composition Time Stamp) of the sample in the timescale of the media + */ + AP4_UI64 GetCts() const { return m_Dts+m_CtsDelta; } + + /** + * Set the CTS (Composition Time Stamp) of the sample in the timescale of the media + */ + void SetCts(AP4_UI64 cts) { m_CtsDelta = (cts > m_Dts) ? (AP4_UI32)(cts-m_Dts) : 0; } + + /** + * Get the CTS Delta (difference between the CTS (Composition Time Stamp) and DTS (Decoding Time Stamp) + * of the sample in the timescale of the media. + */ + AP4_UI32 GetCtsDelta() const { return m_CtsDelta; } + + /** + * Set the CTS Delta (difference between the CTS (Composition Time Stamp) and DTS (Decoding Time Stamp) + * of the sample in the timescale of the media. + */ + void SetCtsDelta(AP4_UI32 delta) { m_CtsDelta = delta; } + + /** + * Get the duration of the sample in the timescale of the media + */ + AP4_UI32 GetDuration() const { return m_Duration; } + + /** + * Set the duration of the sample in the timescale of the media + */ + void SetDuration(AP4_UI32 duration) { m_Duration = duration; } + + /** + * Return whether the sample is a sync (random-access point) sample or not. + */ + bool IsSync() const { return m_IsSync; } + + /** + * Set whether the sample is a sync (random-access point) sample or not. + */ + void SetSync(bool is_sync) { m_IsSync = is_sync; } + +protected: + AP4_ByteStream* m_DataStream; + AP4_Position m_Offset; + AP4_Size m_Size; + AP4_UI32 m_Duration; + AP4_Ordinal m_DescriptionIndex; + AP4_UI64 m_Dts; + AP4_UI32 m_CtsDelta; + bool m_IsSync; +}; + +#endif // _AP4_SAMPLE_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleDescription.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleDescription.cpp index c2a1bbcb1..139b44450 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleDescription.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleDescription.cpp @@ -2,7 +2,7 @@ | | AP4 - Sample Description Objects | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,95 +27,257 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4SampleDescription.h" #include "Ap4EsDescriptor.h" +#include "Ap4SLConfigDescriptor.h" #include "Ap4SampleEntry.h" +#include "Ap4AvccAtom.h" /*---------------------------------------------------------------------- -| AP4_UnknownSampleDescription::AP4_UnknownSampleDescription +| dynamic cast support +---------------------------------------------------------------------*/ -AP4_UnknownSampleDescription::AP4_UnknownSampleDescription(AP4_SampleEntry* entry) : - AP4_SampleDescription(AP4_SampleDescription::TYPE_UNKNOWN), - m_SampleEntry(entry) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_SampleDescription) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_AudioSampleDescription) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_VideoSampleDescription) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_GenericAudioSampleDescription) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_GenericVideoSampleDescription) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MpegSampleDescription) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MpegAudioSampleDescription) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MpegVideoSampleDescription) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MpegSystemSampleDescription) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_AvcSampleDescription) + +/*---------------------------------------------------------------------- +| AP4_SampleDescription::AP4_SampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription::AP4_SampleDescription(Type type, + AP4_UI32 format, + AP4_AtomParent* details) : + m_Type(type), m_Format(format) { + if (details) { + for (AP4_List<AP4_Atom>::Item* item = details->GetChildren().FirstItem(); + item; + item = item->GetNext()) { + AP4_Atom* atom = item->GetData(); + if (atom) { + AP4_Atom* clone = atom->Clone(); + if (clone) m_Details.AddChild(clone); + } + } + } } /*---------------------------------------------------------------------- -| AP4_UnknownSampleDescription::~AP4_UnknownSampleDescription +| AP4_SampleDescription::Clone +---------------------------------------------------------------------*/ -AP4_UnknownSampleDescription::~AP4_UnknownSampleDescription() +AP4_SampleDescription* +AP4_SampleDescription::Clone(AP4_Result* result) { + if (result) *result = AP4_SUCCESS; + AP4_Atom* atom = ToAtom(); + if (atom == NULL) { + if (result) *result = AP4_FAILURE; + return NULL; + } + AP4_SampleEntry* sample_entry = AP4_DYNAMIC_CAST(AP4_SampleEntry, atom); + if (sample_entry == NULL) { + if (result) *result = AP4_ERROR_INTERNAL; + delete atom; + return NULL; + } + + AP4_SampleDescription* clone = sample_entry->ToSampleDescription(); + if (clone == NULL) { + if (result) *result = AP4_ERROR_INTERNAL; + } + + delete atom; + return clone; } /*---------------------------------------------------------------------- -| AP4_UnknownSampleDescription::ToAtom +| AP4_SampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* -AP4_UnknownSampleDescription::ToAtom() const +AP4_SampleDescription::ToAtom() const { - return DNew AP4_SampleEntry(m_SampleEntry->GetType(), - m_SampleEntry->GetDataReferenceIndex()); + return new AP4_SampleEntry(m_Format); +} + +/*---------------------------------------------------------------------- +| AP4_AvcSampleDescription::AP4_AvcSampleDescription ++---------------------------------------------------------------------*/ +AP4_AvcSampleDescription::AP4_AvcSampleDescription(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_UI08 config_version, + AP4_UI08 profile, + AP4_UI08 level, + AP4_UI08 profile_compatibility, + AP4_UI08 length_size, + const AP4_Array<AP4_DataBuffer>& sequence_parameters, + const AP4_Array<AP4_DataBuffer>& picture_parameters) : + AP4_SampleDescription(TYPE_AVC, AP4_SAMPLE_FORMAT_AVC1, NULL), + AP4_VideoSampleDescription(width, height, depth, compressor_name) +{ + m_AvccAtom = new AP4_AvccAtom(config_version, + profile, + level, + profile_compatibility, + length_size, + sequence_parameters, + picture_parameters); + m_Details.AddChild(m_AvccAtom); +} + +/*---------------------------------------------------------------------- +| AP4_AvcSampleDescription::AP4_AvcSampleDescription ++---------------------------------------------------------------------*/ +AP4_AvcSampleDescription::AP4_AvcSampleDescription(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + const AP4_AvccAtom* avcc) : + AP4_SampleDescription(TYPE_AVC, AP4_SAMPLE_FORMAT_AVC1, NULL), + AP4_VideoSampleDescription(width, height, depth, compressor_name) +{ + if (avcc) { + m_AvccAtom = new AP4_AvccAtom(*avcc); + } else { + m_AvccAtom = new AP4_AvccAtom(); + } + m_Details.AddChild(m_AvccAtom); +} + +/*---------------------------------------------------------------------- +| AP4_AvcSampleDescription::AP4_AvcSampleDescription ++---------------------------------------------------------------------*/ +AP4_AvcSampleDescription::AP4_AvcSampleDescription(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_AtomParent* details) : + AP4_SampleDescription(TYPE_AVC, AP4_SAMPLE_FORMAT_AVC1, details), + AP4_VideoSampleDescription(width, height, depth, compressor_name), + m_AvccAtom(NULL) +{ + m_AvccAtom = AP4_DYNAMIC_CAST(AP4_AvccAtom, details->GetChild(AP4_ATOM_TYPE_AVCC)); +} + +/*---------------------------------------------------------------------- +| AP4_AvcSampleDescription::ToAtom ++---------------------------------------------------------------------*/ +AP4_Atom* +AP4_AvcSampleDescription::ToAtom() const +{ + return new AP4_Avc1SampleEntry(m_Width, + m_Height, + m_Depth, + m_CompressorName.GetChars(), + *m_AvccAtom); +} + +/*---------------------------------------------------------------------- +| AP4_MpegSampleDescription::AP4_MpegSampleDescription ++---------------------------------------------------------------------*/ +AP4_MpegSampleDescription::AP4_MpegSampleDescription(AP4_UI32 format, + AP4_EsdsAtom* esds) : + AP4_SampleDescription(TYPE_MPEG, format, NULL), + m_StreamType(0), + m_ObjectTypeId(0), + m_BufferSize(0), + m_MaxBitrate(0), + m_AvgBitrate(0) +{ + if (esds) { + // get the es descriptor + const AP4_EsDescriptor* es_desc = esds->GetEsDescriptor(); + if (es_desc == NULL) return; + + // get the decoder config descriptor + const AP4_DecoderConfigDescriptor* dc_desc = + es_desc->GetDecoderConfigDescriptor(); + if (dc_desc) { + m_StreamType = dc_desc->GetStreamType(); + m_ObjectTypeId = dc_desc->GetObjectTypeIndication(); + m_BufferSize = dc_desc->GetBufferSize(); + m_MaxBitrate = dc_desc->GetMaxBitrate(); + m_AvgBitrate = dc_desc->GetAvgBitrate(); + const AP4_DecoderSpecificInfoDescriptor* dsi_desc = + dc_desc->GetDecoderSpecificInfoDescriptor(); + if (dsi_desc != NULL) { + m_DecoderInfo.SetData(dsi_desc->GetDecoderSpecificInfo().GetData(), + dsi_desc->GetDecoderSpecificInfo().GetDataSize()); + } + } + } } /*---------------------------------------------------------------------- -| AP4_MpegSampleDescription::AP4_MpegSampleDescription +| AP4_MpegSampleDescription::AP4_MpegSampleDescription +---------------------------------------------------------------------*/ AP4_MpegSampleDescription::AP4_MpegSampleDescription( + AP4_UI32 format, StreamType stream_type, OTI oti, const AP4_DataBuffer* decoder_info, AP4_UI32 buffer_size, AP4_UI32 max_bitrate, AP4_UI32 avg_bitrate) : - AP4_SampleDescription(TYPE_MPEG), + AP4_SampleDescription(TYPE_MPEG, format, NULL), m_StreamType(stream_type), m_ObjectTypeId(oti), - m_DecoderInfo(NULL), m_BufferSize(buffer_size), m_MaxBitrate(max_bitrate), m_AvgBitrate(avg_bitrate) { if (decoder_info != NULL) { - m_DecoderInfo = DNew AP4_DataBuffer(*decoder_info); + m_DecoderInfo.SetData(decoder_info->GetData(), decoder_info->GetDataSize()); } } /*---------------------------------------------------------------------- -| AP4_MpegSampleDescription::~AP4_MpegSampleDescription -+---------------------------------------------------------------------*/ -AP4_MpegSampleDescription::~AP4_MpegSampleDescription() -{ - delete m_DecoderInfo; -} - -/*---------------------------------------------------------------------- -| AP4_MpegSampleDescription::CreateEsDescriptor +| AP4_MpegSampleDescription::CreateEsDescriptor +---------------------------------------------------------------------*/ AP4_EsDescriptor* AP4_MpegSampleDescription::CreateEsDescriptor() const { - AP4_EsDescriptor* desc = DNew AP4_EsDescriptor(0); + AP4_EsDescriptor* desc = new AP4_EsDescriptor(0); AP4_DecoderSpecificInfoDescriptor* dsi_desc; - if (m_DecoderInfo) { - dsi_desc = DNew AP4_DecoderSpecificInfoDescriptor(*m_DecoderInfo); + if (m_DecoderInfo.GetDataSize() != 0) { + dsi_desc = new AP4_DecoderSpecificInfoDescriptor(m_DecoderInfo); } else { dsi_desc = NULL; } AP4_DecoderConfigDescriptor* decoder_config = - DNew AP4_DecoderConfigDescriptor(m_StreamType, + new AP4_DecoderConfigDescriptor(m_StreamType, m_ObjectTypeId, m_BufferSize, m_MaxBitrate, m_AvgBitrate, dsi_desc); desc->AddSubDescriptor(decoder_config); + + // add a fixed SL Config + desc->AddSubDescriptor(new AP4_SLConfigDescriptor()); + return desc; } /*---------------------------------------------------------------------- -| AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription +| AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription ++---------------------------------------------------------------------*/ +AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription(AP4_EsdsAtom* esds) : + AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4S, esds) +{ +} + +/*---------------------------------------------------------------------- +| AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription +---------------------------------------------------------------------*/ AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription( StreamType stream_type, @@ -124,7 +286,8 @@ AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription( AP4_UI32 buffer_size, AP4_UI32 max_bitrate, AP4_UI32 avg_bitrate) : - AP4_MpegSampleDescription(stream_type, + AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4S, + stream_type, oti, decoder_info, buffer_size, @@ -134,16 +297,29 @@ AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription( } /*---------------------------------------------------------------------- -| AP4_MpegSystemSampleDescription::ToAtom +| AP4_MpegSystemSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_MpegSystemSampleDescription::ToAtom() const { - return DNew AP4_Mp4sSampleEntry(CreateEsDescriptor()); + return new AP4_Mp4sSampleEntry(CreateEsDescriptor()); } /*---------------------------------------------------------------------- -| AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription +| AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription ++---------------------------------------------------------------------*/ +AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription( + unsigned int sample_rate, + unsigned int sample_size, + unsigned int channel_count, + AP4_EsdsAtom* esds) : + AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4A, esds), + AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) +{ +} + +/*---------------------------------------------------------------------- +| AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription +---------------------------------------------------------------------*/ AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription( OTI oti, @@ -154,30 +330,64 @@ AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription( AP4_UI32 buffer_size, AP4_UI32 max_bitrate, AP4_UI32 avg_bitrate) : - AP4_MpegSampleDescription(AP4_AUDIO_STREAM_TYPE, + AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4A, + AP4_STREAM_TYPE_AUDIO, oti, decoder_info, buffer_size, max_bitrate, avg_bitrate), - m_SampleRate(sample_rate), - m_SampleSize(sample_size), - m_ChannelCount(channel_count) + AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) { } /*---------------------------------------------------------------------- -| AP4_MpegAudioSampleDescription::ToAtom +| AP4_MpegAudioSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_MpegAudioSampleDescription::ToAtom() const { - return DNew AP4_Mp4aSampleEntry(m_SampleRate<<16, + return new AP4_Mp4aSampleEntry(m_SampleRate<<16, m_SampleSize, m_ChannelCount, CreateEsDescriptor()); } /*---------------------------------------------------------------------- -| AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription +| AP4_MpegAudioSampleDescription::GetMpeg4AudioObjectType ++---------------------------------------------------------------------*/ +AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType +AP4_MpegAudioSampleDescription::GetMpeg4AudioObjectType() const +{ + if (m_ObjectTypeId == AP4_OTI_MPEG4_AUDIO && + m_DecoderInfo.GetDataSize() >= 1) { + AP4_UI08 type = m_DecoderInfo.GetData()[0]>>3; + if (type == 31) { + if (m_DecoderInfo.GetDataSize() < 2) return 0; + type = 32+(((m_DecoderInfo.GetData()[0]&0x07)<<3) | + ((m_DecoderInfo.GetData()[1]&0xE0)>>5)); + } + return type; + } else { + return 0; + } +} + +/*---------------------------------------------------------------------- +| AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription ++---------------------------------------------------------------------*/ +AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription( + AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_EsdsAtom* esds) : + + AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4V, esds), + AP4_VideoSampleDescription(width, height, depth, compressor_name) +{ +} + +/*---------------------------------------------------------------------- +| AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription +---------------------------------------------------------------------*/ AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription( OTI oti, @@ -189,78 +399,102 @@ AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription( AP4_UI32 buffer_size, AP4_UI32 max_bitrate, AP4_UI32 avg_bitrate) : - AP4_MpegSampleDescription(AP4_VISUAL_STREAM_TYPE, + AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4V, + AP4_STREAM_TYPE_VISUAL, oti, decoder_info, buffer_size, max_bitrate, avg_bitrate), - m_Width(width), - m_Height(height), - m_Depth(depth), - m_CompressorName(compressor_name) + AP4_VideoSampleDescription(width, height, depth, compressor_name) { } /*---------------------------------------------------------------------- -| AP4_MpegVideoSampleDescription::ToAtom +| AP4_MpegVideoSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_MpegVideoSampleDescription::ToAtom() const { - return DNew AP4_Mp4vSampleEntry(m_Width, + return new AP4_Mp4vSampleEntry(m_Width, m_Height, m_Depth, - m_CompressorName.c_str(), + m_CompressorName.GetChars(), CreateEsDescriptor()); } /*---------------------------------------------------------------------- -| AP4_MpegSampleDescription::GetStreamTypeString +| AP4_MpegSampleDescription::GetStreamTypeString +---------------------------------------------------------------------*/ const char* AP4_MpegSampleDescription::GetStreamTypeString(StreamType type) { switch (type) { - case AP4_FORBIDDEN_STREAM_TYPE: return "INVALID"; - case AP4_OD_STREAM_TYPE: return "Object Descriptor"; - case AP4_CR_STREAM_TYPE: return "CR"; - case AP4_BIFS_STREAM_TYPE: return "BIFS"; - case AP4_VISUAL_STREAM_TYPE: return "Visual"; - case AP4_AUDIO_STREAM_TYPE: return "Audio"; - case AP4_MPEG7_STREAM_TYPE: return "MPEG-7"; - case AP4_IPMP_STREAM_TYPE: return "IPMP"; - case AP4_OCI_STREAM_TYPE: return "OCI"; - case AP4_MPEGJ_STREAM_TYPE: return "MPEG-J"; + case AP4_STREAM_TYPE_FORBIDDEN: return "INVALID"; + case AP4_STREAM_TYPE_OD: return "Object Descriptor"; + case AP4_STREAM_TYPE_CR: return "CR"; + case AP4_STREAM_TYPE_BIFS: return "BIFS"; + case AP4_STREAM_TYPE_VISUAL: return "Visual"; + case AP4_STREAM_TYPE_AUDIO: return "Audio"; + case AP4_STREAM_TYPE_MPEG7: return "MPEG-7"; + case AP4_STREAM_TYPE_IPMP: return "IPMP"; + case AP4_STREAM_TYPE_OCI: return "OCI"; + case AP4_STREAM_TYPE_MPEGJ: return "MPEG-J"; default: return "UNKNOWN"; } } /*---------------------------------------------------------------------- -| AP4_MpegSampleDescription::GetObjectTypeString +| AP4_MpegSampleDescription::GetObjectTypeString +---------------------------------------------------------------------*/ const char* AP4_MpegSampleDescription::GetObjectTypeString(OTI oti) { switch (oti) { - case AP4_MPEG4_SYSTEM_OTI: return "MPEG-4 System"; - case AP4_MPEG4_SYSTEM_COR_OTI: return "MPEG-4 System COR"; - case AP4_MPEG4_VISUAL_OTI: return "MPEG-4 Video"; - case AP4_MPEG4_AUDIO_OTI: return "MPEG-4 Audio"; - case AP4_MPEG2_VISUAL_SIMPLE_OTI: return "MPEG-2 Video Simple Profile"; - case AP4_MPEG2_VISUAL_MAIN_OTI: return "MPEG-2 Video Main Profile"; - case AP4_MPEG2_VISUAL_SNR_OTI: return "MPEG-2 Video SNR"; - case AP4_MPEG2_VISUAL_SPATIAL_OTI: return "MPEG-2 Video Spatial"; - case AP4_MPEG2_VISUAL_HIGH_OTI: return "MPEG-2 Video High"; - case AP4_MPEG2_VISUAL_422_OTI: return "MPEG-2 Video 4:2:2"; - case AP4_MPEG2_AAC_AUDIO_MAIN_OTI: return "MPEG-2 Audio AAC Main Profile"; - case AP4_MPEG2_AAC_AUDIO_LC_OTI: return "MPEG-2 Audio AAC Low Complexity"; - case AP4_MPEG2_AAC_AUDIO_SSRP_OTI: return "MPEG-2 Audio AAC SSRP"; - case AP4_MPEG2_PART3_AUDIO_OTI: return "MPEG-2 Audio Part-3"; - case AP4_MPEG1_VISUAL_OTI: return "MPEG-1 Video"; - case AP4_MPEG1_AUDIO_OTI: return "MPEG-1 Audio"; - case AP4_JPEG_OTI: return "JPEG"; + case AP4_OTI_MPEG4_SYSTEM: return "MPEG-4 System"; + case AP4_OTI_MPEG4_SYSTEM_COR: return "MPEG-4 System COR"; + case AP4_OTI_MPEG4_VISUAL: return "MPEG-4 Video"; + case AP4_OTI_MPEG4_AUDIO: return "MPEG-4 Audio"; + case AP4_OTI_MPEG2_VISUAL_SIMPLE: return "MPEG-2 Video Simple Profile"; + case AP4_OTI_MPEG2_VISUAL_MAIN: return "MPEG-2 Video Main Profile"; + case AP4_OTI_MPEG2_VISUAL_SNR: return "MPEG-2 Video SNR"; + case AP4_OTI_MPEG2_VISUAL_SPATIAL: return "MPEG-2 Video Spatial"; + case AP4_OTI_MPEG2_VISUAL_HIGH: return "MPEG-2 Video High"; + case AP4_OTI_MPEG2_VISUAL_422: return "MPEG-2 Video 4:2:2"; + case AP4_OTI_MPEG2_AAC_AUDIO_MAIN: return "MPEG-2 Audio AAC Main Profile"; + case AP4_OTI_MPEG2_AAC_AUDIO_LC: return "MPEG-2 Audio AAC Low Complexity"; + case AP4_OTI_MPEG2_AAC_AUDIO_SSRP: return "MPEG-2 Audio AAC SSRP"; + case AP4_OTI_MPEG2_PART3_AUDIO: return "MPEG-2 Audio Part-3"; + case AP4_OTI_MPEG1_VISUAL: return "MPEG-1 Video"; + case AP4_OTI_MPEG1_AUDIO: return "MPEG-1 Audio"; + case AP4_OTI_JPEG: return "JPEG"; default: return "UNKNOWN"; } } +/*---------------------------------------------------------------------- +| AP4_MpegAudioSampleDescription::GetMpeg4AudioObjectTypeString ++---------------------------------------------------------------------*/ +const char* +AP4_MpegAudioSampleDescription::GetMpeg4AudioObjectTypeString(Mpeg4AudioObjectType type) +{ + switch (type) { + case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_MAIN: return "AAC Main Profile"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_LC: return "AAC Low Complexity"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_SSR: return "AAC Scalable Sample Rate"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_LTP: return "AAC Long Term Predictor"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_SBR: return "Spectral Band Replication"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_SCALABLE: return "AAC Scalable"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_TWINVQ: return "Twin VQ"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_LC: return "Error Resilient AAC Low Complexity"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_LTP: return "Error Resilient AAC Long Term Prediction"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_SCALABLE: return "Error Resilient AAC Scalable"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_TWINVQ: return "Error Resilient Twin VQ"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_BSAC: return "Error Resilient Bit Sliced Arithmetic Coding"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_LD: return "Error Resilient AAC Low Delay"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_LAYER_1: return "MPEG Layer 1"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_LAYER_2: return "MPEG Layer 2"; + case AP4_MPEG4_AUDIO_OBJECT_TYPE_LAYER_3: return "MPEG Layer 3"; + default: return "UNKNOWN"; + } +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleDescription.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleDescription.h index 1097f7b78..4281be493 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleDescription.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleDescription.h @@ -1,252 +1,446 @@ -/*****************************************************************
-|
-| AP4 - Sample Description Objects
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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_SAMPLE_DESCRIPTION_H_
-#define _AP4_SAMPLE_DESCRIPTION_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4DataBuffer.h"
-#include "Ap4Atom.h"
-#include "Ap4EsDescriptor.h"
-
-/*----------------------------------------------------------------------
-| class references
-+---------------------------------------------------------------------*/
-class AP4_SampleEntry;
-
-/*----------------------------------------------------------------------
-| AP4_SampleDescription
-+---------------------------------------------------------------------*/
-class AP4_SampleDescription
-{
- public:
- // type constants of the sample description
- enum Type {
- TYPE_UNKNOWN = 0x00,
- TYPE_MPEG = 0x01,
- TYPE_ISMACRYP = 0x02
- };
-
- // constructors & destructor
- AP4_SampleDescription(Type type) : m_Type(type) {}
- virtual ~AP4_SampleDescription() {}
-
- // accessors
- Type GetType() const { return m_Type; }
-
- // factories
- virtual AP4_Atom* ToAtom() const = 0;
-
- protected:
- Type m_Type;
-};
-
-/*----------------------------------------------------------------------
-| AP4_UnknownSampleDescription
-+---------------------------------------------------------------------*/
-class AP4_UnknownSampleDescription : public AP4_SampleDescription
-{
- public:
- // methods
- AP4_UnknownSampleDescription(AP4_SampleEntry* sample_entry);
- ~AP4_UnknownSampleDescription();
- AP4_SampleEntry* GetSampleEntry() { return m_SampleEntry; }
- AP4_Atom* ToAtom() const;
-
- protected:
- AP4_SampleEntry* m_SampleEntry;
-};
-
-/*----------------------------------------------------------------------
-| AP4_MpegSampleDescription
-+---------------------------------------------------------------------*/
-class AP4_MpegSampleDescription : public AP4_SampleDescription
-{
- public:
- // types
- typedef AP4_UI08 StreamType;
- typedef AP4_UI08 OTI;
-
- // class methods
- const char* GetStreamTypeString(StreamType type);
- const char* GetObjectTypeString(OTI oti);
-
- // constructors & destructor
- AP4_MpegSampleDescription(StreamType stream_type,
- OTI oti,
- const AP4_DataBuffer* decoder_info,
- AP4_UI32 buffer_size,
- AP4_UI32 max_bitrate,
- AP4_UI32 avg_bitrate);
- virtual ~AP4_MpegSampleDescription();
-
- // accessors
- AP4_Byte GetStreamType() const { return m_StreamType; }
- AP4_Byte GetObjectTypeId() const { return m_ObjectTypeId; }
- const AP4_DataBuffer* GetDecoderInfo() const { return m_DecoderInfo; }
- AP4_UI32 GetBufferSize() const { return m_BufferSize; }
- AP4_UI32 GetMaxBitrate() const { return m_MaxBitrate; }
- AP4_UI32 GetAvgBitrate() const { return m_AvgBitrate; }
-
- // methods
- AP4_EsDescriptor* CreateEsDescriptor() const;
-
- protected:
- // members
- StreamType m_StreamType;
- OTI m_ObjectTypeId;
- AP4_DataBuffer* m_DecoderInfo;
- AP4_UI32 m_BufferSize;
- AP4_UI32 m_MaxBitrate;
- AP4_UI32 m_AvgBitrate;
-
-};
-
-/*----------------------------------------------------------------------
-| AP4_MpegSystemSampleDescription
-+---------------------------------------------------------------------*/
-class AP4_MpegSystemSampleDescription : public AP4_MpegSampleDescription
-{
-public:
- // constructor
- AP4_MpegSystemSampleDescription(StreamType type,
- OTI oti,
- const AP4_DataBuffer* decoder_info,
- AP4_UI32 buffer_size,
- AP4_UI32 max_bitrate,
- AP4_UI32 avg_bitrate);
-
- // methods
- AP4_Atom* ToAtom() const;
-};
-
-/*----------------------------------------------------------------------
-| AP4_MpegAudioSampleDescription
-+---------------------------------------------------------------------*/
-class AP4_MpegAudioSampleDescription : public AP4_MpegSampleDescription
-{
-public:
- // constructor
- AP4_MpegAudioSampleDescription(OTI oti,
- unsigned int sample_rate,
- unsigned int sample_size,
- unsigned int channel_count,
- const AP4_DataBuffer* decoder_info,
- AP4_UI32 buffer_size,
- AP4_UI32 max_bitrate,
- AP4_UI32 avg_bitrate);
-
- // accessors
- AP4_UI32 GetSampleRate() { return m_SampleRate; }
- AP4_UI16 GetSampleSize() { return m_SampleSize; }
- AP4_UI16 GetChannelCount() { return m_ChannelCount; }
-
- // methods
- AP4_Atom* ToAtom() const;
-
-protected:
- // members
- AP4_UI32 m_SampleRate;
- AP4_UI16 m_SampleSize;
- AP4_UI16 m_ChannelCount;
-};
-
-/*----------------------------------------------------------------------
-| AP4_MpegVideoSampleDescription
-+---------------------------------------------------------------------*/
-class AP4_MpegVideoSampleDescription : public AP4_MpegSampleDescription
-{
-public:
- // constructor
- AP4_MpegVideoSampleDescription(OTI oti,
- AP4_UI16 width,
- AP4_UI16 height,
- AP4_UI16 depth,
- const char* compressor_name,
- const AP4_DataBuffer* decoder_info,
- AP4_UI32 buffer_size,
- AP4_UI32 max_bitrate,
- AP4_UI32 avg_bitrate);
-
- // accessors
- AP4_UI32 GetWidth() { return m_Width; }
- AP4_UI16 GetHeight() { return m_Height; }
- AP4_UI16 GetDepth() { return m_Depth; }
- const char* GetCompressorName() { return m_CompressorName.c_str(); }
-
- // methods
- AP4_Atom* ToAtom() const;
-
-protected:
- // members
- AP4_UI16 m_Width;
- AP4_UI16 m_Height;
- AP4_UI16 m_Depth;
- AP4_String m_CompressorName;
-};
-
-/*----------------------------------------------------------------------
-| constants
-+---------------------------------------------------------------------*/
-const AP4_MpegSampleDescription::StreamType AP4_FORBIDDEN_STREAM_TYPE = 0x00;
-const AP4_MpegSampleDescription::StreamType AP4_OD_STREAM_TYPE = 0x01;
-const AP4_MpegSampleDescription::StreamType AP4_CR_STREAM_TYPE = 0x02;
-const AP4_MpegSampleDescription::StreamType AP4_BIFS_STREAM_TYPE = 0x03;
-const AP4_MpegSampleDescription::StreamType AP4_VISUAL_STREAM_TYPE = 0x04;
-const AP4_MpegSampleDescription::StreamType AP4_AUDIO_STREAM_TYPE = 0x05;
-const AP4_MpegSampleDescription::StreamType AP4_MPEG7_STREAM_TYPE = 0x06;
-const AP4_MpegSampleDescription::StreamType AP4_IPMP_STREAM_TYPE = 0x07;
-const AP4_MpegSampleDescription::StreamType AP4_OCI_STREAM_TYPE = 0x08;
-const AP4_MpegSampleDescription::StreamType AP4_MPEGJ_STREAM_TYPE = 0x09;
-
-const AP4_MpegSampleDescription::OTI AP4_MPEG4_SYSTEM_OTI = 0x01;
-const AP4_MpegSampleDescription::OTI AP4_MPEG4_SYSTEM_COR_OTI = 0x02;
-const AP4_MpegSampleDescription::OTI AP4_MPEG4_VISUAL_OTI = 0x20;
-const AP4_MpegSampleDescription::OTI AP4_MPEG4_AUDIO_OTI = 0x40;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_VISUAL_SIMPLE_OTI = 0x60;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_VISUAL_MAIN_OTI = 0x61;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_VISUAL_SNR_OTI = 0x62;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_VISUAL_SPATIAL_OTI = 0x63;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_VISUAL_HIGH_OTI = 0x64;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_VISUAL_422_OTI = 0x65;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_AAC_AUDIO_MAIN_OTI = 0x66;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_AAC_AUDIO_LC_OTI = 0x67;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_AAC_AUDIO_SSRP_OTI = 0x68;
-const AP4_MpegSampleDescription::OTI AP4_MPEG2_PART3_AUDIO_OTI = 0x69;
-const AP4_MpegSampleDescription::OTI AP4_MPEG1_VISUAL_OTI = 0x6A;
-const AP4_MpegSampleDescription::OTI AP4_MPEG1_AUDIO_OTI = 0x6B;
-const AP4_MpegSampleDescription::OTI AP4_JPEG_OTI = 0x6C;
-
+/***************************************************************** +| +| AP4 - Sample Descriptions +| +| 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_SAMPLE_DESCRIPTION_H_ +#define _AP4_SAMPLE_DESCRIPTION_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" +#include "Ap4EsDescriptor.h" +#include "Ap4EsdsAtom.h" +#include "Ap4Array.h" +#include "Ap4AvccAtom.h" +#include "Ap4DynamicCast.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_SampleEntry; +class AP4_DataBuffer; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#define AP4_SAMPLE_FORMAT_MP4A AP4_ATOM_TYPE_MP4A +#define AP4_SAMPLE_FORMAT_MP4V AP4_ATOM_TYPE_MP4V +#define AP4_SAMPLE_FORMAT_AVC1 AP4_ATOM_TYPE_AVC1 +#define AP4_SAMPLE_FORMAT_ALAC AP4_ATOM_TYPE_ALAC + +/*---------------------------------------------------------------------- +| AP4_SampleDescription ++---------------------------------------------------------------------*/ +class AP4_SampleDescription +{ + public: + AP4_IMPLEMENT_DYNAMIC_CAST(AP4_SampleDescription) + + // type constants of the sample description + enum Type { + TYPE_UNKNOWN = 0x00, + TYPE_MPEG = 0x01, + TYPE_PROTECTED = 0x02, + TYPE_AVC = 0x03 + }; + + // constructors & destructor + AP4_SampleDescription(Type type, + AP4_UI32 format, + AP4_AtomParent* details); + virtual ~AP4_SampleDescription() {} + virtual AP4_SampleDescription* Clone(AP4_Result* result = NULL); + + // accessors + Type GetType() const { return m_Type; } + AP4_UI32 GetFormat() const { return m_Format; } + AP4_AtomParent& GetDetails() { return m_Details; } + + // factories + virtual AP4_Atom* ToAtom() const; + + protected: + Type m_Type; + AP4_UI32 m_Format; + AP4_AtomParent m_Details; +}; + +/*---------------------------------------------------------------------- +| AP4_AudioSampleDescription // MIXIN class ++---------------------------------------------------------------------*/ +class AP4_AudioSampleDescription +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST(AP4_AudioSampleDescription) + + // constructor + AP4_AudioSampleDescription(unsigned int sample_rate, + unsigned int sample_size, + unsigned int channel_count) : + m_SampleRate(sample_rate), + m_SampleSize(sample_size), + m_ChannelCount(channel_count) {} + + // accessors + AP4_UI32 GetSampleRate() { return m_SampleRate; } + AP4_UI16 GetSampleSize() { return m_SampleSize; } + AP4_UI16 GetChannelCount() { return m_ChannelCount; } + +protected: + // members + AP4_UI32 m_SampleRate; + AP4_UI16 m_SampleSize; + AP4_UI16 m_ChannelCount; +}; + +/*---------------------------------------------------------------------- +| AP4_VideoSampleDescription // MIXIN class ++---------------------------------------------------------------------*/ +class AP4_VideoSampleDescription +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST(AP4_VideoSampleDescription) + + // constructor + AP4_VideoSampleDescription(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name) : + m_Width(width), + m_Height(height), + m_Depth(depth), + m_CompressorName(compressor_name) {} + + // accessors + AP4_UI16 GetWidth() { return m_Width; } + AP4_UI16 GetHeight() { return m_Height; } + AP4_UI16 GetDepth() { return m_Depth; } + const char* GetCompressorName() { return m_CompressorName.GetChars(); } + +protected: + // members + AP4_UI16 m_Width; + AP4_UI16 m_Height; + AP4_UI16 m_Depth; + AP4_String m_CompressorName; +}; + +/*---------------------------------------------------------------------- +| AP4_GenericAudioSampleDescription ++---------------------------------------------------------------------*/ +class AP4_GenericAudioSampleDescription : public AP4_SampleDescription, + public AP4_AudioSampleDescription +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D2(AP4_GenericAudioSampleDescription, AP4_SampleDescription, AP4_AudioSampleDescription) + + // constructors + AP4_GenericAudioSampleDescription(AP4_UI32 format, + unsigned int sample_rate, + unsigned int sample_size, + unsigned int channel_count, + AP4_AtomParent* details) : + AP4_SampleDescription(TYPE_UNKNOWN, format, details), + AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) {} +}; + +/*---------------------------------------------------------------------- +| AP4_GenericVideoSampleDescription ++---------------------------------------------------------------------*/ +class AP4_GenericVideoSampleDescription : public AP4_SampleDescription, + public AP4_VideoSampleDescription +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D2(AP4_GenericVideoSampleDescription, AP4_SampleDescription, AP4_VideoSampleDescription) + + // constructor + AP4_GenericVideoSampleDescription(AP4_UI32 format, + AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_AtomParent* details) : + AP4_SampleDescription(TYPE_UNKNOWN, format, details), + AP4_VideoSampleDescription(width, height, depth, compressor_name) {} +}; + +/*---------------------------------------------------------------------- +| AP4_AvcSampleDescription ++---------------------------------------------------------------------*/ +class AP4_AvcSampleDescription : public AP4_SampleDescription, + public AP4_VideoSampleDescription +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D2(AP4_AvcSampleDescription, AP4_SampleDescription, AP4_VideoSampleDescription) + + // constructors + AP4_AvcSampleDescription(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + const AP4_AvccAtom* avcc); + + AP4_AvcSampleDescription(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_AtomParent* details); + + AP4_AvcSampleDescription(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_UI08 config_version, + AP4_UI08 profile, + AP4_UI08 level, + AP4_UI08 profile_compatibility, + AP4_UI08 nalu_length_size, + const AP4_Array<AP4_DataBuffer>& sequence_parameters, + const AP4_Array<AP4_DataBuffer>& picture_parameters); + + // accessors + AP4_UI08 GetConfigurationVersion() const { return m_AvccAtom->GetConfigurationVersion(); } + AP4_UI08 GetProfile() const { return m_AvccAtom->GetProfile(); } + AP4_UI08 GetLevel() const { return m_AvccAtom->GetLevel(); } + AP4_UI08 GetProfileCompatibility() const { return m_AvccAtom->GetProfileCompatibility(); } + AP4_UI08 GetNaluLengthSize() const { return m_AvccAtom->GetNaluLengthSize(); } + AP4_Array<AP4_DataBuffer>& GetSequenceParameters() {return m_AvccAtom->GetSequenceParameters(); } + AP4_Array<AP4_DataBuffer>& GetPictureParameters() { return m_AvccAtom->GetPictureParameters(); } + const AP4_DataBuffer& GetRawBytes() const { return m_AvccAtom->GetRawBytes(); } + + // inherited from AP4_SampleDescription + virtual AP4_Atom* ToAtom() const; + + // static methods + static const char* GetProfileName(AP4_UI08 profile) { + return AP4_AvccAtom::GetProfileName(profile); + } + +private: + AP4_AvccAtom* m_AvccAtom; +}; + +/*---------------------------------------------------------------------- +| AP4_MpegSampleDescription ++---------------------------------------------------------------------*/ +class AP4_MpegSampleDescription : public AP4_SampleDescription +{ + public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_MpegSampleDescription, AP4_SampleDescription) + + // types + typedef AP4_UI08 StreamType; + typedef AP4_UI08 OTI; + + // class methods + static const char* GetStreamTypeString(StreamType type); + static const char* GetObjectTypeString(OTI oti); + + // constructors & destructor + AP4_MpegSampleDescription(AP4_UI32 format, + AP4_EsdsAtom* esds); + AP4_MpegSampleDescription(AP4_UI32 format, + StreamType stream_type, + OTI oti, + const AP4_DataBuffer* decoder_info, + AP4_UI32 buffer_size, + AP4_UI32 max_bitrate, + AP4_UI32 avg_bitrate); + + // accessors + AP4_Byte GetStreamType() const { return m_StreamType; } + AP4_Byte GetObjectTypeId() const { return m_ObjectTypeId; } + AP4_UI32 GetBufferSize() const { return m_BufferSize; } + AP4_UI32 GetMaxBitrate() const { return m_MaxBitrate; } + AP4_UI32 GetAvgBitrate() const { return m_AvgBitrate; } + const AP4_DataBuffer& GetDecoderInfo() const { return m_DecoderInfo; } + + + // methods + AP4_EsDescriptor* CreateEsDescriptor() const; + + protected: + // members + AP4_UI32 m_Format; + StreamType m_StreamType; + OTI m_ObjectTypeId; + AP4_UI32 m_BufferSize; + AP4_UI32 m_MaxBitrate; + AP4_UI32 m_AvgBitrate; + AP4_DataBuffer m_DecoderInfo; +}; + +/*---------------------------------------------------------------------- +| AP4_MpegSystemSampleDescription ++---------------------------------------------------------------------*/ +class AP4_MpegSystemSampleDescription : public AP4_MpegSampleDescription +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_MpegSystemSampleDescription, AP4_MpegSampleDescription) + + // constructor + AP4_MpegSystemSampleDescription(AP4_EsdsAtom* esds); + AP4_MpegSystemSampleDescription(StreamType stream_type, + OTI oti, + const AP4_DataBuffer* decoder_info, + AP4_UI32 buffer_size, + AP4_UI32 max_bitrate, + AP4_UI32 avg_bitrate); + + // methods + AP4_Atom* ToAtom() const; +}; + +/*---------------------------------------------------------------------- +| AP4_MpegAudioSampleDescription ++---------------------------------------------------------------------*/ +class AP4_MpegAudioSampleDescription : public AP4_MpegSampleDescription, + public AP4_AudioSampleDescription +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D2(AP4_MpegAudioSampleDescription, AP4_MpegSampleDescription, AP4_AudioSampleDescription) + + // types + typedef AP4_UI08 Mpeg4AudioObjectType; + + // class methods + static const char* GetMpeg4AudioObjectTypeString(Mpeg4AudioObjectType type); + + // constructor + AP4_MpegAudioSampleDescription(unsigned int sample_rate, + unsigned int sample_size, + unsigned int channel_count, + AP4_EsdsAtom* esds); + + AP4_MpegAudioSampleDescription(OTI oti, + unsigned int sample_rate, + unsigned int sample_size, + unsigned int channel_count, + const AP4_DataBuffer* decoder_info, + AP4_UI32 buffer_size, + AP4_UI32 max_bitrate, + AP4_UI32 avg_bitrate); + + // methods + AP4_Atom* ToAtom() const; + + /** + * For sample descriptions of MPEG-4 audio tracks (i.e GetObjectTypeId() + * returns AP4_OTI_MPEG4_AUDIO), this method returns the MPEG4 Audio Object + * Type. For other sample descriptions, this method returns 0. + */ + Mpeg4AudioObjectType GetMpeg4AudioObjectType() const; +}; + +/*---------------------------------------------------------------------- +| AP4_MpegVideoSampleDescription ++---------------------------------------------------------------------*/ +class AP4_MpegVideoSampleDescription : public AP4_MpegSampleDescription, + public AP4_VideoSampleDescription +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D2(AP4_MpegVideoSampleDescription, AP4_MpegSampleDescription, AP4_VideoSampleDescription) + + // constructor + AP4_MpegVideoSampleDescription(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_EsdsAtom* esds); + + AP4_MpegVideoSampleDescription(OTI oti, + AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + const AP4_DataBuffer* decoder_info, + AP4_UI32 buffer_size, + AP4_UI32 max_bitrate, + AP4_UI32 avg_bitrate); + + // methods + AP4_Atom* ToAtom() const; +}; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_FORBIDDEN = 0x00; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_OD = 0x01; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_CR = 0x02; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_BIFS = 0x03; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_VISUAL = 0x04; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_AUDIO = 0x05; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_MPEG7 = 0x06; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_IPMP = 0x07; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_OCI = 0x08; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_MPEGJ = 0x09; +const AP4_MpegSampleDescription::StreamType AP4_STREAM_TYPE_TEXT = 0x0D; + +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG4_SYSTEM = 0x01; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG4_SYSTEM_COR = 0x02; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG4_TEXT = 0x08; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG4_VISUAL = 0x20; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG4_AUDIO = 0x40; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_VISUAL_SIMPLE = 0x60; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_VISUAL_MAIN = 0x61; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_VISUAL_SNR = 0x62; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_VISUAL_SPATIAL = 0x63; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_VISUAL_HIGH = 0x64; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_VISUAL_422 = 0x65; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_AAC_AUDIO_MAIN = 0x66; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_AAC_AUDIO_LC = 0x67; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_AAC_AUDIO_SSRP = 0x68; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG2_PART3_AUDIO = 0x69; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG1_VISUAL = 0x6A; +const AP4_MpegSampleDescription::OTI AP4_OTI_MPEG1_AUDIO = 0x6B; +const AP4_MpegSampleDescription::OTI AP4_OTI_JPEG = 0x6C; +// ==> Start patch MPC const AP4_MpegSampleDescription::OTI AP4_NERO_VOBSUB = 0xE0;
-
-#endif // _AP4_SAMPLE_DESCRIPTION_H_
-
+// <== End patch MPC
+ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_MAIN = 1; /**< AAC Main Profile */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_LC = 2; /**< AAC Low Complexity */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_SSR = 3; /**< AAC Scalable Sample Rate */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_LTP = 4; /**< AAC Long Term Predictor */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_SBR = 5; /**< Spectral Band Replication */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_SCALABLE = 6; /**< AAC Scalable */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_TWINVQ = 7; /**< Twin VQ */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_LC = 17; /**< Error Resilient AAC Low Complexity */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_LTP = 19; /**< Error Resilient AAC Long Term Prediction */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_SCALABLE = 20; /**< Error Resilient AAC Scalable */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_TWINVQ = 21; /**< Error Resilient Twin VQ */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_BSAC = 22; /**< Error Resilient Bit Sliced Arithmetic Coding */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_LD = 23; /**< Error Resilient AAC Low Delay */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_LAYER_1 = 32; /**< MPEG Layer 1 */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_LAYER_2 = 33; /**< MPEG Layer 2 */ +const AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MPEG4_AUDIO_OBJECT_TYPE_LAYER_3 = 34; /**< MPEG Layer 3 */ + +#endif // _AP4_SAMPLE_DESCRIPTION_H_ + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleEntry.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleEntry.cpp index 6e3567d38..76b916e6d 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleEntry.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleEntry.cpp @@ -1,933 +1,1074 @@ -/*****************************************************************
-|
-| AP4 - sample entries
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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 "Ap4SampleEntry.h"
-#include "Ap4Utils.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4TimsAtom.h"
-#include "Ap4SampleDescription.h"
-#include "Ap4FtabAtom.h"
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::AP4_SampleEntry
-+---------------------------------------------------------------------*/
-AP4_SampleEntry::AP4_SampleEntry(AP4_Atom::Type format,
- AP4_UI16 data_reference_index) :
- AP4_ContainerAtom(format, AP4_ATOM_HEADER_SIZE+8, false),
- m_DataReferenceIndex(data_reference_index)
-{
- m_Reserved1[0] = 0;
- m_Reserved1[1] = 0;
- m_Reserved1[2] = 0;
- m_Reserved1[3] = 0;
- m_Reserved1[4] = 0;
- m_Reserved1[5] = 0;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::AP4_SampleEntry
-+---------------------------------------------------------------------*/
-AP4_SampleEntry::AP4_SampleEntry(AP4_Atom::Type format,
- AP4_Size size) :
- AP4_ContainerAtom(format, size)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::AP4_SampleEntry
-+---------------------------------------------------------------------*/
-AP4_SampleEntry::AP4_SampleEntry(AP4_Atom::Type format,
- AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_ContainerAtom(format, size)
-{
- // read the fields before the children atoms
- AP4_Size fields_size = GetFieldsSize();
- ReadFields(stream);
-
- // read children atoms (ex: esds and maybe others)
- ReadChildren(atom_factory, stream, size-AP4_ATOM_HEADER_SIZE-fields_size);
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::GetFieldsSize
-+---------------------------------------------------------------------*/
-AP4_Size
-AP4_SampleEntry::GetFieldsSize()
-{
- return 8;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::ReadFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SampleEntry::ReadFields(AP4_ByteStream& stream)
-{
- stream.Read(m_Reserved1, sizeof(m_Reserved1), NULL);
- stream.ReadUI16(m_DataReferenceIndex);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SampleEntry::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // reserved1
- result = stream.Write(m_Reserved1, sizeof(m_Reserved1));
- if (AP4_FAILED(result)) return result;
-
- // data reference index
- result = stream.WriteUI16(m_DataReferenceIndex);
- if (AP4_FAILED(result)) return result;
-
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::Write
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SampleEntry::Write(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // write the header
- result = WriteHeader(stream);
- if (AP4_FAILED(result)) return result;
-
- // write the fields
- result = WriteFields(stream);
- if (AP4_FAILED(result)) return result;
-
- // write the children atoms
- return m_Children.Apply(AP4_AtomListWriter(stream));
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SampleEntry::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("data_reference_index", m_DataReferenceIndex);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::Inspect
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SampleEntry::Inspect(AP4_AtomInspector& inspector)
-{
- // inspect the header
- InspectHeader(inspector);
-
- // inspect the fields
- InspectFields(inspector);
-
- // inspect children
- m_Children.Apply(AP4_AtomListInspector(inspector));
-
- // finish
- inspector.EndElement();
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::OnChildChanged
-+---------------------------------------------------------------------*/
-void
-AP4_SampleEntry::OnChildChanged(AP4_Atom*)
-{
- // remcompute our size
- m_Size = GetHeaderSize()+GetFieldsSize();
- m_Children.Apply(AP4_AtomSizeAdder(m_Size));
-
- // update our parent
- if (m_Parent) m_Parent->OnChildChanged(this);
-}
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry::ToSampleDescription
-+---------------------------------------------------------------------*/
-AP4_SampleDescription*
-AP4_SampleEntry::ToSampleDescription()
-{
- return DNew AP4_UnknownSampleDescription(this);
-}
-
-/*----------------------------------------------------------------------
-| AP4_MpegSampleEntry::AP4_MpegSampleEntry
-+---------------------------------------------------------------------*/
-AP4_MpegSampleEntry::AP4_MpegSampleEntry(AP4_Atom::Type format,
- AP4_EsDescriptor* descriptor) :
- AP4_SampleEntry(format)
-{
- if (descriptor) AddChild(DNew AP4_EsdsAtom(descriptor));
-}
-
-/*----------------------------------------------------------------------
-| AP4_MpegSampleEntry::AP4_MpegSampleEntry
-+---------------------------------------------------------------------*/
-AP4_MpegSampleEntry::AP4_MpegSampleEntry(AP4_Atom::Type format,
- AP4_Size size) :
- AP4_SampleEntry(format, size)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_MpegSampleEntry::AP4_MpegSampleEntry
-+---------------------------------------------------------------------*/
-AP4_MpegSampleEntry::AP4_MpegSampleEntry(AP4_Atom::Type format,
- AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_SampleEntry(format, size, stream, atom_factory)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_MpegSampleEntry::AP4_MpegSampleEntry
-+---------------------------------------------------------------------*/
-const AP4_DecoderConfigDescriptor*
-AP4_MpegSampleEntry::GetDecoderConfigDescriptor()
-{
- AP4_Atom* child = GetChild(AP4_ATOM_TYPE_ESDS);
-
- if(!child && (child = GetChild(AP4_ATOM_TYPE_WAVE)))
- {
- if(AP4_ContainerAtom* wave = dynamic_cast<AP4_ContainerAtom*>(child))
- {
- child = wave->GetChild(AP4_ATOM_TYPE_ESDS);
- }
- }
-
- if (child) {
- AP4_EsdsAtom* esds = (AP4_EsdsAtom*)child;
-
- // get the es descriptor
- const AP4_EsDescriptor* es_desc = esds->GetEsDescriptor();
- if (es_desc == NULL) return NULL;
-
- // get the decoder config descriptor
- return es_desc->GetDecoderConfigDescriptor();
- } else {
- return NULL;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry
-+---------------------------------------------------------------------*/
-AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry(AP4_EsDescriptor* descriptor) :
- AP4_MpegSampleEntry(AP4_ATOM_TYPE_MP4S, descriptor)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry
-+---------------------------------------------------------------------*/
-AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_MpegSampleEntry(AP4_ATOM_TYPE_MP4S, size, stream, atom_factory)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_Mp4sSampleEntry::ToSampleDescription
-+---------------------------------------------------------------------*/
-AP4_SampleDescription*
-AP4_Mp4sSampleEntry::ToSampleDescription()
-{
- // get the decoder config descriptor
- const AP4_DecoderConfigDescriptor* dc_desc;
- dc_desc = GetDecoderConfigDescriptor();
- if (dc_desc == NULL) return NULL;
- const AP4_DataBuffer* dsi = NULL;
- const AP4_DecoderSpecificInfoDescriptor* dsi_desc =
- dc_desc->GetDecoderSpecificInfoDescriptor();
- if (dsi_desc != NULL) {
- dsi = &dsi_desc->GetDecoderSpecificInfo();
- }
-
- // create a sample description
- return DNew AP4_MpegSystemSampleDescription(
- dc_desc->GetStreamType(),
- dc_desc->GetObjectTypeIndication(),
- dsi,
- dc_desc->GetBufferSize(),
- dc_desc->GetMaxBitrate(),
- dc_desc->GetAvgBitrate());
-}
-
-/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry::AP4_AudioSampleEntry
-+---------------------------------------------------------------------*/
-AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format,
- AP4_EsDescriptor* descriptor,
- AP4_UI32 sample_rate,
- AP4_UI16 sample_size,
- AP4_UI16 channel_count) :
- AP4_MpegSampleEntry(format, descriptor),
- m_DescriptionVersion(0),
- m_RevisionLevel(0),
- m_Vendor(0),
- m_SampleRate(sample_rate),
- m_ChannelCount(channel_count),
- m_SampleSize(sample_size)
-{
- m_Size += 20;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry::AP4_AudioSampleEntry
-+---------------------------------------------------------------------*/
-AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format,
- AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_MpegSampleEntry(format, size)
-{
- // read fields
- ReadFields(stream);
-
- // must be called after m_DescriptionVersion was already set
- AP4_Size fields_size = GetFieldsSize();
-
- // read children atoms (ex: esds and maybe others)
- ReadChildren(atom_factory, stream, size-AP4_ATOM_HEADER_SIZE-fields_size);
-}
-
-/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry::AP4_AudioSampleEntry
-+---------------------------------------------------------------------*/
-AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format,
- AP4_Size size) :
- AP4_MpegSampleEntry(format, size)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry::GetFieldsSize
-+---------------------------------------------------------------------*/
-AP4_Size
-AP4_AudioSampleEntry::GetFieldsSize()
-{
- return AP4_SampleEntry::GetFieldsSize() + 20 + (m_DescriptionVersion == 1 ? 16 : 0);
-}
-
-/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry::ReadFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AudioSampleEntry::ReadFields(AP4_ByteStream& stream)
-{
- // sample entry
- AP4_Result result = AP4_SampleEntry::ReadFields(stream);
- if (result < 0) return result;
-
- // read the fields of this class
- stream.ReadUI16(m_DescriptionVersion);
- stream.ReadUI16(m_RevisionLevel);
- stream.ReadUI32(m_Vendor);
-
- m_SamplesPerPacket = 0;
- m_BytesPerPacket = 0;
- m_BytesPerSample = 0;
- m_BytesPerFrame = 0;
-
- if(m_DescriptionVersion == 0 || m_DescriptionVersion == 1)
- {
- stream.ReadUI16(m_ChannelCount);
- stream.ReadUI16(m_SampleSize);
- stream.ReadUI16(m_CompressionID);
- stream.ReadUI16(m_PacketSize);
- stream.ReadUI32(m_SampleRate);
-
- if(m_DescriptionVersion == 1)
- {
- stream.ReadUI32(m_SamplesPerPacket);
- stream.ReadUI32(m_BytesPerPacket);
- stream.ReadUI32(m_BytesPerFrame);
- stream.ReadUI32(m_BytesPerSample);
- }
- }
- else if(m_DescriptionVersion == 2)
- {
- char junk[16];
-
- stream.Read(junk, 12); // always 00 03 00 10 FF FE 00 00 00 01 00 00
-
- AP4_UI32 SizeOfStructOnly;
- stream.ReadUI32(SizeOfStructOnly);
- if(SizeOfStructOnly < 0x48) return AP4_FAILURE;
-
- m_SampleSize = 0;
-
- AP4_UI64 SampleRate;
- stream.ReadUI64(SampleRate);
- m_SampleRate = (AP4_UI32)(*(double*)&SampleRate * 65536);
-
- AP4_UI32 ChannelCount;
- stream.ReadUI32(ChannelCount);
- m_ChannelCount = (AP4_UI16)ChannelCount;
-
- stream.Read(junk, 4); // always 7f 00 00 00
- stream.Read(junk, 16); // constBitsPerChannel, formatSpecificFlags, constBytesPerAudioPacket, constLPCMFramesPerAudioPacket
-
- SizeOfStructOnly -= 0x48;
-
- if(SizeOfStructOnly > 0)
- {
- AP4_Offset offset;
- stream.Tell(offset);
- stream.Seek(offset + SizeOfStructOnly);
- }
- }
- else
- {
- return AP4_FAILURE;
- }
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AudioSampleEntry::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // write the fields of the base class
- result = AP4_SampleEntry::WriteFields(stream);
-
- //
- result = stream.WriteUI16(m_DescriptionVersion);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI16(m_RevisionLevel);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_Vendor);
- if (AP4_FAILED(result)) return result;
-
- // channel count
- result = stream.WriteUI16(m_ChannelCount);
- if (AP4_FAILED(result)) return result;
-
- // sample size
- result = stream.WriteUI16(m_SampleSize);
- if (AP4_FAILED(result)) return result;
-
- // predefined1
- result = stream.WriteUI16(m_CompressionID);
- if (AP4_FAILED(result)) return result;
-
- // reserved3
- result = stream.WriteUI16(m_PacketSize);
- if (AP4_FAILED(result)) return result;
-
- // sample rate
- result = stream.WriteUI32(m_SampleRate);
- if (AP4_FAILED(result)) return result;
-
- if(m_DescriptionVersion == 1)
- {
- result = stream.WriteUI32(m_SamplesPerPacket);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_BytesPerPacket);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_BytesPerFrame);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_BytesPerSample);
- if (AP4_FAILED(result)) return result;
- }
- else if(m_DescriptionVersion != 0)
- {
- return AP4_FAILURE;
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AudioSampleEntry::InspectFields(AP4_AtomInspector& inspector)
-{
- // dump the fields from the base class
- AP4_SampleEntry::InspectFields(inspector);
-
- // fields
- inspector.AddField("channel_count", m_ChannelCount);
- inspector.AddField("sample_size", m_SampleSize);
- inspector.AddField("sample_rate", m_SampleRate>>16);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry::ToSampleDescription
-+---------------------------------------------------------------------*/
-AP4_SampleDescription*
-AP4_AudioSampleEntry::ToSampleDescription()
-{
- // get the decoder config descriptor
- const AP4_DecoderConfigDescriptor* dc_desc;
- dc_desc = GetDecoderConfigDescriptor();
- if (dc_desc == NULL) return NULL;
- const AP4_DataBuffer* dsi = NULL;
- const AP4_DecoderSpecificInfoDescriptor* dsi_desc =
- dc_desc->GetDecoderSpecificInfoDescriptor();
- if (dsi_desc != NULL) {
- dsi = &dsi_desc->GetDecoderSpecificInfo();
- }
-
- // create a sample description
- return DNew AP4_MpegAudioSampleDescription(
- dc_desc->GetObjectTypeIndication(),
- m_SampleRate>>16,
- m_SampleSize,
- m_ChannelCount,
- dsi,
- dc_desc->GetBufferSize(),
- dc_desc->GetMaxBitrate(),
- dc_desc->GetAvgBitrate());
-}
-
-/*----------------------------------------------------------------------
-| AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry
-+---------------------------------------------------------------------*/
-AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry(AP4_UI32 sample_rate,
- AP4_UI16 sample_size,
- AP4_UI16 channel_count,
- AP4_EsDescriptor* descriptor) :
- AP4_AudioSampleEntry(AP4_ATOM_TYPE_MP4A,
- descriptor,
- sample_rate,
- sample_size,
- channel_count)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry
-+---------------------------------------------------------------------*/
-AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_AudioSampleEntry(AP4_ATOM_TYPE_MP4A, size, stream, atom_factory)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_VisualSampleEntry::AP4_VisualSampleEntry
-+---------------------------------------------------------------------*/
-AP4_VisualSampleEntry::AP4_VisualSampleEntry(
- AP4_Atom::Type format,
- AP4_EsDescriptor* descriptor,
- AP4_UI16 width,
- AP4_UI16 height,
- AP4_UI16 depth,
- const char* compressor_name) :
- AP4_MpegSampleEntry(format, descriptor),
- m_Predefined1(0),
- m_Reserved2(0),
- m_Width(width),
- m_Height(height),
- m_HorizResolution(0x00480000),
- m_VertResolution(0x00480000),
- m_Reserved3(0),
- m_FrameCount(1),
- m_CompressorName(compressor_name),
- m_Depth(depth),
- m_Predefined3(0xFFFF)
-{
- memset(m_Predefined2, 0, sizeof(m_Predefined2));
- m_Size += 70;
-}
-
-/*----------------------------------------------------------------------
-| AP4_VisualSampleEntry::AP4_VisualSampleEntry
-+---------------------------------------------------------------------*/
-AP4_VisualSampleEntry::AP4_VisualSampleEntry(AP4_Atom::Type format,
- AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_MpegSampleEntry(format, size)
-{
- // read fields
- AP4_Size fields_size = GetFieldsSize();
- ReadFields(stream);
-
- // read children atoms (ex: esds and maybe others)
- ReadChildren(atom_factory, stream, size-AP4_ATOM_HEADER_SIZE-fields_size);
-}
-
-/*----------------------------------------------------------------------
-| AP4_VisualSampleEntry::GetFieldsSize
-+---------------------------------------------------------------------*/
-AP4_Size
-AP4_VisualSampleEntry::GetFieldsSize()
-{
- return AP4_SampleEntry::GetFieldsSize()+70;
-}
-
-/*----------------------------------------------------------------------
-| AP4_VisualSampleEntry::ReadFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_VisualSampleEntry::ReadFields(AP4_ByteStream& stream)
-{
- // sample entry
- AP4_Result result = AP4_SampleEntry::ReadFields(stream);
- if (result < 0) return result;
-
- // read fields from this class
- stream.ReadUI16(m_Predefined1);
- stream.ReadUI16(m_Reserved2);
- stream.Read(m_Predefined2, sizeof(m_Predefined2), NULL);
- stream.ReadUI16(m_Width);
- stream.ReadUI16(m_Height);
- stream.ReadUI32(m_HorizResolution);
- stream.ReadUI32(m_VertResolution);
- stream.ReadUI32(m_Reserved3);
- stream.ReadUI16(m_FrameCount);
-
- char compressor_name[33];
- stream.Read(compressor_name, 32);
- int name_length = compressor_name[0];
- if (name_length < 32) {
- compressor_name[name_length+1] = 0;
- m_CompressorName = &compressor_name[1];
- }
-
- stream.ReadUI16(m_Depth);
- stream.ReadUI16(m_Predefined3);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_VisualSampleEntry::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_VisualSampleEntry::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // write the fields of the base class
- result = AP4_SampleEntry::WriteFields(stream);
- if (AP4_FAILED(result)) return result;
-
- // predefined1
- result = stream.WriteUI16(m_Predefined1);
- if (AP4_FAILED(result)) return result;
-
- // reserved2
- result = stream.WriteUI16(m_Reserved2);
- if (AP4_FAILED(result)) return result;
-
- // predefined2
- result = stream.Write(m_Predefined2, sizeof(m_Predefined2));
- if (AP4_FAILED(result)) return result;
-
- // width
- result = stream.WriteUI16(m_Width);
- if (AP4_FAILED(result)) return result;
-
- // height
- result = stream.WriteUI16(m_Height);
- if (AP4_FAILED(result)) return result;
-
- // horizontal resolution
- result = stream.WriteUI32(m_HorizResolution);
- if (AP4_FAILED(result)) return result;
-
- // vertical resolution
- result = stream.WriteUI32(m_VertResolution);
- if (AP4_FAILED(result)) return result;
-
- // reserved3
- result = stream.WriteUI32(m_Reserved3);
- if (AP4_FAILED(result)) return result;
-
- // frame count
- result = stream.WriteUI16(m_FrameCount);
- if (AP4_FAILED(result)) return result;
-
- // compressor name
- unsigned char compressor_name[32];
- unsigned int name_length = m_CompressorName.length();
- if (name_length > 31) name_length = 31;
- compressor_name[0] = name_length;
- for (unsigned int i=0; i<name_length; i++) {
- compressor_name[i+1] = m_CompressorName[i];
- }
- for (unsigned int i=name_length+1; i<32; i++) {
- compressor_name[i] = 0;
- }
- result = stream.Write(compressor_name, 32);
- if (AP4_FAILED(result)) return result;
-
- // depth
- result = stream.WriteUI16(m_Depth);
- if (AP4_FAILED(result)) return result;
-
- // predefined3
- result = stream.WriteUI16(m_Predefined3);
- if (AP4_FAILED(result)) return result;
-
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_VisualSampleEntry::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_VisualSampleEntry::InspectFields(AP4_AtomInspector& inspector)
-{
- // dump the fields of the base class
- AP4_SampleEntry::InspectFields(inspector);
-
- // fields
- inspector.AddField("width", m_Width);
- inspector.AddField("height", m_Height);
- inspector.AddField("compressor", m_CompressorName.c_str());
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_VisualSampleEntry::ToSampleDescription
-+---------------------------------------------------------------------*/
-AP4_SampleDescription*
-AP4_VisualSampleEntry::ToSampleDescription()
-{
- // get the decoder config descriptor
- const AP4_DecoderConfigDescriptor* dc_desc;
- dc_desc = GetDecoderConfigDescriptor();
- if (dc_desc == NULL) return NULL;
- const AP4_DataBuffer* dsi = NULL;
- const AP4_DecoderSpecificInfoDescriptor* dsi_desc =
- dc_desc->GetDecoderSpecificInfoDescriptor();
- if (dsi_desc != NULL) {
- dsi = &dsi_desc->GetDecoderSpecificInfo();
- }
-
- // create a sample description
- return DNew AP4_MpegVideoSampleDescription(
- dc_desc->GetObjectTypeIndication(),
- m_Width,
- m_Height,
- m_Depth,
- m_CompressorName.c_str(),
- dsi,
- dc_desc->GetBufferSize(),
- dc_desc->GetMaxBitrate(),
- dc_desc->GetAvgBitrate());
-}
-
-/*----------------------------------------------------------------------
-| AP4_Mp4vSampleEntry::AP4_Mp4vSampleEntry
-+---------------------------------------------------------------------*/
-AP4_Mp4vSampleEntry::AP4_Mp4vSampleEntry(AP4_UI16 width,
- AP4_UI16 height,
- AP4_UI16 depth,
- const char* compressor_name,
- AP4_EsDescriptor* descriptor) :
- AP4_VisualSampleEntry(AP4_ATOM_TYPE_MP4V,
- descriptor,
- width,
- height,
- depth,
- compressor_name)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_Mp4vSampleEntry::AP4_Mp4aSampleEntry
-+---------------------------------------------------------------------*/
-AP4_Mp4vSampleEntry::AP4_Mp4vSampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_VisualSampleEntry(AP4_ATOM_TYPE_MP4V, size, stream, atom_factory)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_Avc1SampleEntry::AP4_Avc1SampleEntry
-+---------------------------------------------------------------------*/
-AP4_Avc1SampleEntry::AP4_Avc1SampleEntry(AP4_UI16 width,
- AP4_UI16 height,
- AP4_UI16 depth,
- const char* compressor_name,
- AP4_EsDescriptor* descriptor) :
- AP4_VisualSampleEntry(AP4_ATOM_TYPE_AVC1,
- descriptor,
- width,
- height,
- depth,
- compressor_name)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_Avc1SampleEntry::AP4_Avc1SampleEntry
-+---------------------------------------------------------------------*/
-AP4_Avc1SampleEntry::AP4_Avc1SampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_VisualSampleEntry(AP4_ATOM_TYPE_AVC1, size, stream, atom_factory)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry
-+---------------------------------------------------------------------*/
-AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry(AP4_UI16 hint_track_version,
- AP4_UI16 highest_compatible_version,
- AP4_UI32 max_packet_size,
- AP4_UI32 timescale):
- AP4_SampleEntry(AP4_ATOM_TYPE_RTP),
- m_HintTrackVersion(hint_track_version),
- m_HighestCompatibleVersion(highest_compatible_version),
- m_MaxPacketSize(max_packet_size)
-{
- // build an atom for timescale
- AddChild(DNew AP4_TimsAtom(timescale));
-}
-
-/*----------------------------------------------------------------------
-| AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry
-+---------------------------------------------------------------------*/
-AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory):
- AP4_SampleEntry(AP4_ATOM_TYPE_RTP, size)
-{
- // read fields
- AP4_Size fields_size = GetFieldsSize();
- ReadFields(stream);
-
- // read children atoms (ex: esds and maybe others)
- ReadChildren(atom_factory, stream, size-AP4_ATOM_HEADER_SIZE-fields_size);
-}
-
-/*----------------------------------------------------------------------
-| AP4_RtpHintSampleEntry::~AP4_RtpHintSampleEntry
-+---------------------------------------------------------------------*/
-AP4_RtpHintSampleEntry::~AP4_RtpHintSampleEntry()
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_RtpHintSampleEntry::GetFieldsSize
-+---------------------------------------------------------------------*/
-AP4_Size
-AP4_RtpHintSampleEntry::GetFieldsSize()
-{
- return AP4_SampleEntry::GetFieldsSize()+8;
-}
-
-/*----------------------------------------------------------------------
-| AP4_RtpHintSampleEntry::ReadFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_RtpHintSampleEntry::ReadFields(AP4_ByteStream& stream)
-{
- // sample entry
- AP4_Result result = AP4_SampleEntry::ReadFields(stream);
- if (result < 0) return result;
-
- // data
- result = stream.ReadUI16(m_HintTrackVersion);
- if (AP4_FAILED(result)) return result;
- result = stream.ReadUI16(m_HighestCompatibleVersion);
- if (AP4_FAILED(result)) return result;
- result = stream.ReadUI32(m_MaxPacketSize);
- if (AP4_FAILED(result)) return result;
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_RtpHintSampleEntry::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_RtpHintSampleEntry::WriteFields(AP4_ByteStream& stream)
-{
- // sample entry
- AP4_Result result = AP4_SampleEntry::WriteFields(stream);
- if (AP4_FAILED(result)) return result;
-
- // data
- result = stream.WriteUI16(m_HintTrackVersion);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI16(m_HighestCompatibleVersion);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_MaxPacketSize);
- if (AP4_FAILED(result)) return result;
-
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_RtpHintSampleEntry::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_RtpHintSampleEntry::InspectFields(AP4_AtomInspector& inspector)
-{
- // sample entry
- AP4_SampleEntry::InspectFields(inspector);
-
- // fields
- inspector.AddField("hint_track_version", m_HintTrackVersion);
- inspector.AddField("highest_compatible_version", m_HighestCompatibleVersion);
- inspector.AddField("max_packet_size", m_MaxPacketSize);
-
- return AP4_SUCCESS;
-}
-
+/***************************************************************** +| +| AP4 - sample entries +| +| 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 "Ap4SampleEntry.h" +#include "Ap4Utils.h" +#include "Ap4AtomFactory.h" +#include "Ap4TimsAtom.h" +#include "Ap4SampleDescription.h" +#include "Ap4AvccAtom.h" +// ==> Start patch MPC +#include "Ap4FtabAtom.h" +// <== End patch MPC + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_SampleEntry) + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::AP4_SampleEntry ++---------------------------------------------------------------------*/ +AP4_SampleEntry::AP4_SampleEntry(AP4_Atom::Type format, + AP4_UI16 data_reference_index) : + AP4_ContainerAtom(format), + m_DataReferenceIndex(data_reference_index) +{ + m_Reserved1[0] = 0; + m_Reserved1[1] = 0; + m_Reserved1[2] = 0; + m_Reserved1[3] = 0; + m_Reserved1[4] = 0; + m_Reserved1[5] = 0; + m_Size32 += 8; +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::AP4_SampleEntry ++---------------------------------------------------------------------*/ +AP4_SampleEntry::AP4_SampleEntry(AP4_Atom::Type format, + AP4_Size size) : + AP4_ContainerAtom(format, size, false) +{ +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::AP4_SampleEntry ++---------------------------------------------------------------------*/ +AP4_SampleEntry::AP4_SampleEntry(AP4_Atom::Type format, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_ContainerAtom(format, size, false) +{ + // read the fields before the children atoms + AP4_Size fields_size = GetFieldsSize(); + ReadFields(stream); + + // read children atoms (ex: esds and maybe others) + ReadChildren(atom_factory, stream, size-AP4_ATOM_HEADER_SIZE-fields_size); +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::GetFieldsSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_SampleEntry::GetFieldsSize() +{ + return 8; +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::ReadFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SampleEntry::ReadFields(AP4_ByteStream& stream) +{ + stream.Read(m_Reserved1, sizeof(m_Reserved1)); + stream.ReadUI16(m_DataReferenceIndex); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SampleEntry::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // reserved1 + result = stream.Write(m_Reserved1, sizeof(m_Reserved1)); + if (AP4_FAILED(result)) return result; + + // data reference index + result = stream.WriteUI16(m_DataReferenceIndex); + if (AP4_FAILED(result)) return result; + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::Write ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SampleEntry::Write(AP4_ByteStream& stream) +{ + AP4_Result result; + + // write the header + result = WriteHeader(stream); + if (AP4_FAILED(result)) return result; + + // write the fields + result = WriteFields(stream); + if (AP4_FAILED(result)) return result; + + // write the children atoms + return m_Children.Apply(AP4_AtomListWriter(stream)); +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SampleEntry::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("data_reference_index", m_DataReferenceIndex); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::Inspect ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SampleEntry::Inspect(AP4_AtomInspector& inspector) +{ + // inspect the header + InspectHeader(inspector); + + // inspect the fields + InspectFields(inspector); + + // inspect children + m_Children.Apply(AP4_AtomListInspector(inspector)); + + // finish + inspector.EndElement(); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::OnChildChanged ++---------------------------------------------------------------------*/ +void +AP4_SampleEntry::OnChildChanged(AP4_Atom*) +{ + // remcompute our size + AP4_UI64 size = GetHeaderSize()+GetFieldsSize(); + m_Children.Apply(AP4_AtomSizeAdder(size)); + m_Size32 = (AP4_UI32)size; + + // update our parent + if (m_Parent) m_Parent->OnChildChanged(this); +} + +/*---------------------------------------------------------------------- +| AP4_SampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_SampleEntry::ToSampleDescription() +{ + return new AP4_SampleDescription(AP4_SampleDescription::TYPE_UNKNOWN, m_Type, this); +} + +/*---------------------------------------------------------------------- +| AP4_MpegSystemSampleEntry::AP4_MpegSystemSampleEntry ++---------------------------------------------------------------------*/ +AP4_MpegSystemSampleEntry::AP4_MpegSystemSampleEntry( + AP4_UI32 type, + AP4_EsDescriptor* descriptor) : + AP4_SampleEntry(type) +{ + if (descriptor) AddChild(new AP4_EsdsAtom(descriptor)); +} + +/*---------------------------------------------------------------------- +| AP4_MpegSystemSampleEntry::AP4_MpegSystemSampleEntry ++---------------------------------------------------------------------*/ +AP4_MpegSystemSampleEntry::AP4_MpegSystemSampleEntry( + AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_SampleEntry(type, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_MpegSystemSampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_MpegSystemSampleEntry::ToSampleDescription() +{ + return new AP4_MpegSystemSampleDescription( + AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS))); +} + +/*---------------------------------------------------------------------- +| AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry ++---------------------------------------------------------------------*/ +AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry(AP4_EsDescriptor* descriptor) : + AP4_MpegSystemSampleEntry(AP4_ATOM_TYPE_MP4S, descriptor) +{ +} + +/*---------------------------------------------------------------------- +| AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry ++---------------------------------------------------------------------*/ +AP4_Mp4sSampleEntry::AP4_Mp4sSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_MpegSystemSampleEntry(AP4_ATOM_TYPE_MP4S, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_Mp4sSampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_Mp4sSampleEntry::ToSampleDescription() +{ + // create a sample description + return new AP4_MpegSystemSampleDescription( + AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS))); +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::AP4_AudioSampleEntry ++---------------------------------------------------------------------*/ +AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format, + AP4_UI32 sample_rate, + AP4_UI16 sample_size, + AP4_UI16 channel_count) : + AP4_SampleEntry(format), + m_QtVersion(0), + m_QtRevision(0), + m_QtVendor(0), + m_ChannelCount(channel_count), + m_SampleSize(sample_size), + m_QtCompressionId(0), + m_QtPacketSize(0), + m_SampleRate(sample_rate), + m_QtV1SamplesPerPacket(0), + m_QtV1BytesPerPacket(0), + m_QtV1BytesPerFrame(0), + m_QtV1BytesPerSample(0), + m_QtV2StructSize(0), + m_QtV2SampleRate64(0.0), + m_QtV2ChannelCount(0), + m_QtV2Reserved(0), + m_QtV2BitsPerChannel(0), + m_QtV2FormatSpecificFlags(0), + m_QtV2BytesPerAudioPacket(0), + m_QtV2LPCMFramesPerAudioPacket(0) +{ + m_Size32 += 20; +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::AP4_AudioSampleEntry ++---------------------------------------------------------------------*/ +AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_SampleEntry(format, size) +{ + // read fields + ReadFields(stream); + AP4_Size fields_size = GetFieldsSize(); + + // read children atoms (ex: esds and maybe others) + ReadChildren(atom_factory, stream, size-AP4_ATOM_HEADER_SIZE-fields_size); +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::GetFieldsSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_AudioSampleEntry::GetFieldsSize() +{ + AP4_Size size = AP4_SampleEntry::GetFieldsSize()+20; + if (m_QtVersion == 1) { + size += 16; + } else if (m_QtVersion == 2) { + size += 36+m_QtV2Extension.GetDataSize(); + } + + return size; +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::GetSampleRate ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_AudioSampleEntry::GetSampleRate() +{ + if (m_QtVersion == 2) { + return (AP4_UI32)(m_QtV2SampleRate64); + } else { + return m_SampleRate>>16; + } +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::GetChannelCount ++---------------------------------------------------------------------*/ +AP4_UI16 +AP4_AudioSampleEntry::GetChannelCount() +{ + if (m_QtVersion == 2) { + return m_QtV2ChannelCount; + } else { + return m_ChannelCount; + } +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::ReadFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AudioSampleEntry::ReadFields(AP4_ByteStream& stream) +{ + // sample entry + AP4_Result result = AP4_SampleEntry::ReadFields(stream); + if (result < 0) return result; + + // read the fields of this class + stream.ReadUI16(m_QtVersion); + stream.ReadUI16(m_QtRevision); + stream.ReadUI32(m_QtVendor); + stream.ReadUI16(m_ChannelCount); + stream.ReadUI16(m_SampleSize); + stream.ReadUI16(m_QtCompressionId); + stream.ReadUI16(m_QtPacketSize); + stream.ReadUI32(m_SampleRate); + + // if this is a QT V1 entry, read the extension + if (m_QtVersion == 1) { + stream.ReadUI32(m_QtV1SamplesPerPacket); + stream.ReadUI32(m_QtV1BytesPerPacket); + stream.ReadUI32(m_QtV1BytesPerFrame); + stream.ReadUI32(m_QtV1BytesPerSample); + } else if (m_QtVersion == 2) { + stream.ReadUI32(m_QtV2StructSize); + stream.ReadDouble(m_QtV2SampleRate64); + stream.ReadUI32(m_QtV2ChannelCount); + stream.ReadUI32(m_QtV2Reserved); + stream.ReadUI32(m_QtV2BitsPerChannel); + stream.ReadUI32(m_QtV2FormatSpecificFlags); + stream.ReadUI32(m_QtV2BytesPerAudioPacket); + stream.ReadUI32(m_QtV2LPCMFramesPerAudioPacket); + if (m_QtV2StructSize > 72) { + unsigned int ext_size = m_QtV2StructSize-72; + m_QtV2Extension.SetDataSize(ext_size); + stream.Read(m_QtV2Extension.UseData(), ext_size); + } + m_QtV1SamplesPerPacket = + m_QtV1BytesPerPacket = + m_QtV1BytesPerFrame = + m_QtV1BytesPerSample = 0; + } else { + m_QtV1SamplesPerPacket = 0; + m_QtV1BytesPerPacket = 0; + m_QtV1BytesPerFrame = 0; + m_QtV1BytesPerSample = 0; + m_QtV2StructSize = 0; + m_QtV2SampleRate64 = 0.0; + m_QtV2ChannelCount = 0; + m_QtV2Reserved = 0; + m_QtV2BitsPerChannel = 0; + m_QtV2FormatSpecificFlags = 0; + m_QtV2BytesPerAudioPacket = 0; + m_QtV2LPCMFramesPerAudioPacket = 0; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AudioSampleEntry::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // write the fields of the base class + result = AP4_SampleEntry::WriteFields(stream); + + // QT version + result = stream.WriteUI16(m_QtVersion); + if (AP4_FAILED(result)) return result; + + // QT revision + result = stream.WriteUI16(m_QtRevision); + if (AP4_FAILED(result)) return result; + + // QT vendor + result = stream.WriteUI32(m_QtVendor); + if (AP4_FAILED(result)) return result; + + // channel count + result = stream.WriteUI16(m_ChannelCount); + if (AP4_FAILED(result)) return result; + + // sample size + result = stream.WriteUI16(m_SampleSize); + if (AP4_FAILED(result)) return result; + + // QT compression ID + result = stream.WriteUI16(m_QtCompressionId); + if (AP4_FAILED(result)) return result; + + // QT packet size + result = stream.WriteUI16(m_QtPacketSize); + if (AP4_FAILED(result)) return result; + + // sample rate + result = stream.WriteUI32(m_SampleRate); + if (AP4_FAILED(result)) return result; + + if (m_QtVersion == 1) { + result = stream.WriteUI32(m_QtV1SamplesPerPacket); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_QtV1BytesPerPacket); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_QtV1BytesPerFrame); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_QtV1BytesPerSample); + if (AP4_FAILED(result)) return result; + } else if (m_QtVersion == 2) { + stream.WriteUI32(m_QtV2StructSize); + stream.WriteDouble(m_QtV2SampleRate64); + stream.WriteUI32(m_QtV2ChannelCount); + stream.WriteUI32(m_QtV2Reserved); + stream.WriteUI32(m_QtV2BitsPerChannel); + stream.WriteUI32(m_QtV2FormatSpecificFlags); + stream.WriteUI32(m_QtV2BytesPerAudioPacket); + stream.WriteUI32(m_QtV2LPCMFramesPerAudioPacket); + if (m_QtV2Extension.GetDataSize()) { + stream.Write(m_QtV2Extension.GetData(), + m_QtV2Extension.GetDataSize()); + } + } + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AudioSampleEntry::InspectFields(AP4_AtomInspector& inspector) +{ + // dump the fields from the base class + AP4_SampleEntry::InspectFields(inspector); + + // fields + inspector.AddField("channel_count", GetChannelCount()); + inspector.AddField("sample_size", GetSampleSize()); + inspector.AddField("sample_rate", GetSampleRate()); + if (m_QtVersion) { + inspector.AddField("qt_version", m_QtVersion); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_AudioSampleEntry::ToSampleDescription() +{ + // create a sample description + return new AP4_GenericAudioSampleDescription( + m_Type, + GetSampleRate(), + GetSampleSize(), + GetChannelCount(), + this); +} + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry::ToTargetSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_AudioSampleEntry::ToTargetSampleDescription(AP4_UI32 format) +{ + switch (format) { + case AP4_ATOM_TYPE_MP4A: + return new AP4_MpegAudioSampleDescription( + GetSampleRate(), + GetSampleSize(), + GetChannelCount(), + AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS))); + + default: + return new AP4_GenericAudioSampleDescription( + format, + GetSampleRate(), + GetSampleSize(), + GetChannelCount(), + this); + } +} + +/*---------------------------------------------------------------------- +| AP4_MpegAudioSampleEntry::AP4_MpegAudioSampleEntry ++---------------------------------------------------------------------*/ +AP4_MpegAudioSampleEntry::AP4_MpegAudioSampleEntry( + AP4_UI32 type, + AP4_UI32 sample_rate, + AP4_UI16 sample_size, + AP4_UI16 channel_count, + AP4_EsDescriptor* descriptor) : + AP4_AudioSampleEntry(type, sample_rate, sample_size, channel_count) +{ + if (descriptor) AddChild(new AP4_EsdsAtom(descriptor)); +} + +/*---------------------------------------------------------------------- +| AP4_MpegAudioSampleEntry::AP4_MpegAudioSampleEntry ++---------------------------------------------------------------------*/ +AP4_MpegAudioSampleEntry::AP4_MpegAudioSampleEntry( + AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_AudioSampleEntry(type, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_MpegAudioSampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_MpegAudioSampleEntry::ToSampleDescription() +{ + // find the esds atom + AP4_EsdsAtom* esds = AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS)); + if (esds == NULL) { + // check if this is a quicktime style sample description + if (m_QtVersion > 0) { + esds = AP4_DYNAMIC_CAST(AP4_EsdsAtom, FindChild("wave/esds")); + } + } + + // create a sample description + return new AP4_MpegAudioSampleDescription(GetSampleRate(), + GetSampleSize(), + GetChannelCount(), + esds); +} + +/*---------------------------------------------------------------------- +| AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry ++---------------------------------------------------------------------*/ +AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry(AP4_UI32 sample_rate, + AP4_UI16 sample_size, + AP4_UI16 channel_count, + AP4_EsDescriptor* descriptor) : + AP4_MpegAudioSampleEntry(AP4_ATOM_TYPE_MP4A, + sample_rate, + sample_size, + channel_count, + descriptor) +{ +} + +/*---------------------------------------------------------------------- +| AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry ++---------------------------------------------------------------------*/ +AP4_Mp4aSampleEntry::AP4_Mp4aSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_MpegAudioSampleEntry(AP4_ATOM_TYPE_MP4A, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_VisualSampleEntry::AP4_VisualSampleEntry ++---------------------------------------------------------------------*/ +AP4_VisualSampleEntry::AP4_VisualSampleEntry( + AP4_Atom::Type format, + AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name) : + AP4_SampleEntry(format), + m_Predefined1(0), + m_Reserved2(0), + m_Width(width), + m_Height(height), + m_HorizResolution(0x00480000), + m_VertResolution(0x00480000), + m_Reserved3(0), + m_FrameCount(1), + m_CompressorName(compressor_name), + m_Depth(depth), + m_Predefined3(0xFFFF) +{ + memset(m_Predefined2, 0, sizeof(m_Predefined2)); + m_Size32 += 70; +} + +/*---------------------------------------------------------------------- +| AP4_VisualSampleEntry::AP4_VisualSampleEntry ++---------------------------------------------------------------------*/ +AP4_VisualSampleEntry::AP4_VisualSampleEntry(AP4_Atom::Type format, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_SampleEntry(format, size) +{ + // read fields + AP4_Size fields_size = GetFieldsSize(); + ReadFields(stream); + + // read children atoms (ex: esds and maybe others) + ReadChildren(atom_factory, stream, size-AP4_ATOM_HEADER_SIZE-fields_size); +} + +/*---------------------------------------------------------------------- +| AP4_VisualSampleEntry::GetFieldsSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_VisualSampleEntry::GetFieldsSize() +{ + return AP4_SampleEntry::GetFieldsSize()+70; +} + +/*---------------------------------------------------------------------- +| AP4_VisualSampleEntry::ReadFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_VisualSampleEntry::ReadFields(AP4_ByteStream& stream) +{ + // sample entry + AP4_Result result = AP4_SampleEntry::ReadFields(stream); + if (result < 0) return result; + + // read fields from this class + stream.ReadUI16(m_Predefined1); + stream.ReadUI16(m_Reserved2); + stream.Read(m_Predefined2, sizeof(m_Predefined2)); + stream.ReadUI16(m_Width); + stream.ReadUI16(m_Height); + stream.ReadUI32(m_HorizResolution); + stream.ReadUI32(m_VertResolution); + stream.ReadUI32(m_Reserved3); + stream.ReadUI16(m_FrameCount); + + char compressor_name[33]; + stream.Read(compressor_name, 32); + int name_length = compressor_name[0]; + if (name_length < 32) { + compressor_name[name_length+1] = 0; // force null termination + m_CompressorName = &compressor_name[1]; + } + + stream.ReadUI16(m_Depth); + stream.ReadUI16(m_Predefined3); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_VisualSampleEntry::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_VisualSampleEntry::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // write the fields of the base class + result = AP4_SampleEntry::WriteFields(stream); + if (AP4_FAILED(result)) return result; + + // predefined1 + result = stream.WriteUI16(m_Predefined1); + if (AP4_FAILED(result)) return result; + + // reserved2 + result = stream.WriteUI16(m_Reserved2); + if (AP4_FAILED(result)) return result; + + // predefined2 + result = stream.Write(m_Predefined2, sizeof(m_Predefined2)); + if (AP4_FAILED(result)) return result; + + // width + result = stream.WriteUI16(m_Width); + if (AP4_FAILED(result)) return result; + + // height + result = stream.WriteUI16(m_Height); + if (AP4_FAILED(result)) return result; + + // horizontal resolution + result = stream.WriteUI32(m_HorizResolution); + if (AP4_FAILED(result)) return result; + + // vertical resolution + result = stream.WriteUI32(m_VertResolution); + if (AP4_FAILED(result)) return result; + + // reserved3 + result = stream.WriteUI32(m_Reserved3); + if (AP4_FAILED(result)) return result; + + // frame count + result = stream.WriteUI16(m_FrameCount); + if (AP4_FAILED(result)) return result; + + // compressor name + unsigned char compressor_name[32]; + unsigned int name_length = m_CompressorName.GetLength(); + if (name_length > 31) name_length = 31; + compressor_name[0] = name_length; + for (unsigned int i=0; i<name_length; i++) { + compressor_name[i+1] = m_CompressorName[i]; + } + for (unsigned int i=name_length+1; i<32; i++) { + compressor_name[i] = 0; + } + result = stream.Write(compressor_name, 32); + if (AP4_FAILED(result)) return result; + + // depth + result = stream.WriteUI16(m_Depth); + if (AP4_FAILED(result)) return result; + + // predefined3 + result = stream.WriteUI16(m_Predefined3); + if (AP4_FAILED(result)) return result; + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_VisualSampleEntry::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_VisualSampleEntry::InspectFields(AP4_AtomInspector& inspector) +{ + // dump the fields of the base class + AP4_SampleEntry::InspectFields(inspector); + + // fields + inspector.AddField("width", m_Width); + inspector.AddField("height", m_Height); + inspector.AddField("compressor", m_CompressorName.GetChars()); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_VisualSampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_VisualSampleEntry::ToSampleDescription() +{ + // create a sample description + return new AP4_GenericVideoSampleDescription( + m_Type, + m_Width, + m_Height, + m_Depth, + m_CompressorName.GetChars(), + this); +} + +/*---------------------------------------------------------------------- +| AP4_VisualSampleEntry::ToTargetSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_VisualSampleEntry::ToTargetSampleDescription(AP4_UI32 format) +{ + switch (format) { + case AP4_ATOM_TYPE_AVC1: + return new AP4_AvcSampleDescription( + m_Width, + m_Height, + m_Depth, + m_CompressorName.GetChars(), + this); + + case AP4_ATOM_TYPE_MP4V: + return new AP4_MpegVideoSampleDescription( + m_Width, + m_Height, + m_Depth, + m_CompressorName.GetChars(), + AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS))); + + default: + return new AP4_GenericVideoSampleDescription( + format, + m_Width, + m_Height, + m_Depth, + m_CompressorName.GetChars(), + this); + } +} + +/*---------------------------------------------------------------------- +| AP4_MpegVideoSampleEntry::AP4_MpegVideoSampleEntry ++---------------------------------------------------------------------*/ +AP4_MpegVideoSampleEntry::AP4_MpegVideoSampleEntry( + AP4_UI32 type, + AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_EsDescriptor* descriptor) : + AP4_VisualSampleEntry(type, + width, + height, + depth, + compressor_name) +{ + if (descriptor) AddChild(new AP4_EsdsAtom(descriptor)); +} + +/*---------------------------------------------------------------------- +| AP4_MpegVideoSampleEntry::AP4_MpegVideoSampleEntry ++---------------------------------------------------------------------*/ +AP4_MpegVideoSampleEntry::AP4_MpegVideoSampleEntry( + AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_VisualSampleEntry(type, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_MpegVideoSampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_MpegVideoSampleEntry::ToSampleDescription() +{ + // create a sample description + return new AP4_MpegVideoSampleDescription( + m_Width, + m_Height, + m_Depth, + m_CompressorName.GetChars(), + AP4_DYNAMIC_CAST(AP4_EsdsAtom, GetChild(AP4_ATOM_TYPE_ESDS))); +} + +/*---------------------------------------------------------------------- +| AP4_Mp4vSampleEntry::AP4_Mp4vSampleEntry ++---------------------------------------------------------------------*/ +AP4_Mp4vSampleEntry::AP4_Mp4vSampleEntry(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_EsDescriptor* descriptor) : + AP4_MpegVideoSampleEntry(AP4_ATOM_TYPE_MP4V, + width, + height, + depth, + compressor_name, + descriptor) +{ +} + +/*---------------------------------------------------------------------- +| AP4_Mp4vSampleEntry::AP4_Mp4aSampleEntry ++---------------------------------------------------------------------*/ +AP4_Mp4vSampleEntry::AP4_Mp4vSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_MpegVideoSampleEntry(AP4_ATOM_TYPE_MP4V, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_Avc1SampleEntry::AP4_Avc1SampleEntry ++---------------------------------------------------------------------*/ +AP4_Avc1SampleEntry::AP4_Avc1SampleEntry(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + const AP4_AvccAtom& avcc) : + AP4_VisualSampleEntry(AP4_ATOM_TYPE_AVC1, + width, + height, + depth, + compressor_name) +{ + AddChild(new AP4_AvccAtom(avcc)); +} + +/*---------------------------------------------------------------------- +| AP4_Avc1SampleEntry::AP4_Avc1SampleEntry ++---------------------------------------------------------------------*/ +AP4_Avc1SampleEntry::AP4_Avc1SampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_VisualSampleEntry(AP4_ATOM_TYPE_AVC1, size, stream, atom_factory) +{ +} + +/*---------------------------------------------------------------------- +| AP4_Avc1SampleEntry::ToSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_Avc1SampleEntry::ToSampleDescription() +{ + return new AP4_AvcSampleDescription( + m_Width, + m_Height, + m_Depth, + m_CompressorName.GetChars(), + AP4_DYNAMIC_CAST(AP4_AvccAtom, GetChild(AP4_ATOM_TYPE_AVCC))); +} + +/*---------------------------------------------------------------------- +| AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry ++---------------------------------------------------------------------*/ +AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry(AP4_UI16 hint_track_version, + AP4_UI16 highest_compatible_version, + AP4_UI32 max_packet_size, + AP4_UI32 timescale): + AP4_SampleEntry(AP4_ATOM_TYPE_RTP_), + m_HintTrackVersion(hint_track_version), + m_HighestCompatibleVersion(highest_compatible_version), + m_MaxPacketSize(max_packet_size) +{ + // build an atom for timescale + AddChild(new AP4_TimsAtom(timescale)); +} + +/*---------------------------------------------------------------------- +| AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry ++---------------------------------------------------------------------*/ +AP4_RtpHintSampleEntry::AP4_RtpHintSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory): + AP4_SampleEntry(AP4_ATOM_TYPE_RTP_, size) +{ + // read fields + AP4_Size fields_size = GetFieldsSize(); + ReadFields(stream); + + // read children atoms (ex: esds and maybe others) + ReadChildren(atom_factory, stream, size-AP4_ATOM_HEADER_SIZE-fields_size); +} + +/*---------------------------------------------------------------------- +| AP4_RtpHintSampleEntry::~AP4_RtpHintSampleEntry ++---------------------------------------------------------------------*/ +AP4_RtpHintSampleEntry::~AP4_RtpHintSampleEntry() +{ +} + +/*---------------------------------------------------------------------- +| AP4_RtpHintSampleEntry::GetFieldsSize ++---------------------------------------------------------------------*/ +AP4_Size +AP4_RtpHintSampleEntry::GetFieldsSize() +{ + return AP4_SampleEntry::GetFieldsSize()+8; +} + +/*---------------------------------------------------------------------- +| AP4_RtpHintSampleEntry::ReadFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_RtpHintSampleEntry::ReadFields(AP4_ByteStream& stream) +{ + // sample entry + AP4_Result result = AP4_SampleEntry::ReadFields(stream); + if (result < 0) return result; + + // data + result = stream.ReadUI16(m_HintTrackVersion); + if (AP4_FAILED(result)) return result; + result = stream.ReadUI16(m_HighestCompatibleVersion); + if (AP4_FAILED(result)) return result; + result = stream.ReadUI32(m_MaxPacketSize); + if (AP4_FAILED(result)) return result; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_RtpHintSampleEntry::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_RtpHintSampleEntry::WriteFields(AP4_ByteStream& stream) +{ + // sample entry + AP4_Result result = AP4_SampleEntry::WriteFields(stream); + if (AP4_FAILED(result)) return result; + + // data + result = stream.WriteUI16(m_HintTrackVersion); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI16(m_HighestCompatibleVersion); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_MaxPacketSize); + if (AP4_FAILED(result)) return result; + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_RtpHintSampleEntry::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_RtpHintSampleEntry::InspectFields(AP4_AtomInspector& inspector) +{ + // sample entry + AP4_SampleEntry::InspectFields(inspector); + + // fields + inspector.AddField("hint_track_version", m_HintTrackVersion); + inspector.AddField("highest_compatible_version", m_HighestCompatibleVersion); + inspector.AddField("max_packet_size", m_MaxPacketSize); + + return AP4_SUCCESS; +} + +// ==> Start patch MPC /*----------------------------------------------------------------------
| AP4_TextSampleEntry::AP4_TextSampleEntry
+---------------------------------------------------------------------*/
@@ -1020,7 +1161,7 @@ AP4_TextSampleEntry::InspectFields(AP4_AtomInspector& inspector) return AP4_SUCCESS;
}
-
+ /*----------------------------------------------------------------------
| AP4_Tx3gSampleEntry::AP4_Tx3gSampleEntry
+---------------------------------------------------------------------*/
@@ -1149,23 +1290,26 @@ AP4_Tx3gSampleEntry::GetFontNameById(AP4_Ordinal Id, AP4_String& Name) return AP4_FAILURE;
}
+ + + /*----------------------------------------------------------------------
| AP4_AC3SampleEntry::AP4_AC3SampleEntry
+---------------------------------------------------------------------*/
-AP4_AC3SampleEntry::AP4_AC3SampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_AudioSampleEntry(AP4_ATOM_TYPE__AC3, size)
+AP4_AC3SampleEntry::AP4_AC3SampleEntry(AP4_UI32 sample_rate, + AP4_UI16 sample_size, + AP4_UI16 channel_count) :
+ AP4_AudioSampleEntry(AP4_ATOM_TYPE__AC3, sample_rate, sample_size, channel_count)
{
-
- // read fields
- ReadFields(stream);
-
- AP4_Size fields_size = GetFieldsSize();
-
- // read children atoms (ex: esds and maybe others)
- ReadChildren(atom_factory, stream, size-AP4_ATOM_HEADER_SIZE-fields_size);
}
+ +AP4_AC3SampleEntry::AP4_AC3SampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_AudioSampleEntry(AP4_ATOM_TYPE__AC3, size, stream, atom_factory) +{ +} +
/*----------------------------------------------------------------------
| AP4_AC3SampleEntry::ReadFields
@@ -1238,3 +1382,4 @@ AP4_AC3SampleEntry::GetFieldsSize() {
return AP4_AudioSampleEntry::GetFieldsSize() + 11;
}
+// <== End patch MPC
\ No newline at end of file diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleEntry.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleEntry.h index 7220cfd58..6031d5a84 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleEntry.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleEntry.h @@ -1,305 +1,369 @@ -/*****************************************************************
-|
-| AP4 - sample entries
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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_SAMPLE_ENTRY_H_
-#define _AP4_SAMPLE_ENTRY_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4List.h"
-#include "Ap4Atom.h"
-#include "Ap4EsdsAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4ContainerAtom.h"
-
-/*----------------------------------------------------------------------
-| class references
-+---------------------------------------------------------------------*/
-class AP4_SampleDescription;
-
-/*----------------------------------------------------------------------
-| AP4_SampleEntry
-+---------------------------------------------------------------------*/
-class AP4_SampleEntry : public AP4_ContainerAtom
-{
- public:
- // methods
- AP4_SampleEntry(AP4_Atom::Type format, AP4_UI16 data_ref_index = 1);
- AP4_SampleEntry(AP4_Atom::Type format,
- AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
- AP4_UI16 GetDataReferenceIndex() { return m_DataReferenceIndex; }
- virtual AP4_Result Write(AP4_ByteStream& stream);
- virtual AP4_Result Inspect(AP4_AtomInspector& inspector);
- virtual AP4_SampleDescription* ToSampleDescription();
-
- // AP4_AtomParent methods
- virtual void OnChildChanged(AP4_Atom* child);
-
- protected:
- // constructor
- AP4_SampleEntry(AP4_Atom::Type format, AP4_Size size);
-
- // methods
- virtual AP4_Size GetFieldsSize();
- virtual AP4_Result ReadFields(AP4_ByteStream& stream);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
-
- // members
- AP4_UI08 m_Reserved1[6]; // = 0
- AP4_UI16 m_DataReferenceIndex;
-};
-
-/*----------------------------------------------------------------------
-| AP4_MpegSampleEntry
-+---------------------------------------------------------------------*/
-class AP4_MpegSampleEntry : public AP4_SampleEntry
-{
-protected:
- // constructor
- AP4_MpegSampleEntry(AP4_Atom::Type format);
- AP4_MpegSampleEntry(AP4_Atom::Type format, AP4_Size size);
- AP4_MpegSampleEntry(AP4_Atom::Type format,
- AP4_EsDescriptor* descriptor);
- AP4_MpegSampleEntry(AP4_Atom::Type format,
- AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
-
- // methods
- const AP4_DecoderConfigDescriptor* GetDecoderConfigDescriptor();
-};
-
-/*----------------------------------------------------------------------
-| AP4_Mp4sSampleEntry
-+---------------------------------------------------------------------*/
-class AP4_Mp4sSampleEntry : public AP4_MpegSampleEntry
-{
- public:
- // constructors
- AP4_Mp4sSampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
- AP4_Mp4sSampleEntry(AP4_EsDescriptor* descriptor);
-
- // methods
- AP4_SampleDescription* ToSampleDescription();
-};
-
-/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry
-+---------------------------------------------------------------------*/
-class AP4_AudioSampleEntry : public AP4_MpegSampleEntry
-{
- public:
- // methods
- AP4_AudioSampleEntry(AP4_Atom::Type format,
- AP4_EsDescriptor* descriptor,
- AP4_UI32 sample_rate,
- AP4_UI16 sample_size,
- AP4_UI16 channel_count);
- AP4_AudioSampleEntry(AP4_Atom::Type format,
- AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
- AP4_AudioSampleEntry(AP4_Atom::Type format,
- AP4_Size size);
-
- // accessors
- AP4_UI32 GetSampleRate() { return m_SampleRate>>16; }
- AP4_UI16 GetSampleSize() { return m_SampleSize; }
- AP4_UI16 GetChannelCount() { return m_ChannelCount; }
- AP4_UI32 GetSamplesPerPacket(){ return m_SamplesPerPacket; }
- AP4_UI32 GetBytesPerPacket(){ return m_BytesPerPacket; }
- AP4_UI32 GetBytesPerFrame(){ return m_BytesPerFrame; }
- AP4_UI32 GetBytesPerSample(){ return m_BytesPerSample; }
-
- // methods
- AP4_SampleDescription* ToSampleDescription();
-
-protected:
- // methods
- virtual AP4_Size GetFieldsSize();
- virtual AP4_Result ReadFields(AP4_ByteStream& stream);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
-
- // members
- AP4_UI16 m_DescriptionVersion;
- AP4_UI16 m_RevisionLevel;
- AP4_UI32 m_Vendor;
- AP4_UI16 m_ChannelCount;
- AP4_UI16 m_SampleSize;
- AP4_UI16 m_CompressionID;
- AP4_UI16 m_PacketSize;
- AP4_UI32 m_SampleRate;
- // m_Version == 1 ?
- AP4_UI32 m_SamplesPerPacket;
- AP4_UI32 m_BytesPerPacket;
- AP4_UI32 m_BytesPerFrame;
- AP4_UI32 m_BytesPerSample;
-};
-
-/*----------------------------------------------------------------------
-| AP4_Mp4aSampleEntry
-+---------------------------------------------------------------------*/
-class AP4_Mp4aSampleEntry : public AP4_AudioSampleEntry
-{
- public:
- // constructors
- AP4_Mp4aSampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
- AP4_Mp4aSampleEntry(AP4_UI32 sample_rate,
- AP4_UI16 sample_size,
- AP4_UI16 channel_count,
- AP4_EsDescriptor* descriptor);
-};
-
-/*----------------------------------------------------------------------
-| AP4_VisualSampleEntry
-+---------------------------------------------------------------------*/
-class AP4_VisualSampleEntry : public AP4_MpegSampleEntry
-{
- public:
- // methods
- AP4_VisualSampleEntry(AP4_Atom::Type format,
- AP4_EsDescriptor* descriptor,
- AP4_UI16 width,
- AP4_UI16 height,
- AP4_UI16 depth,
- const char* compressor_name);
- AP4_VisualSampleEntry(AP4_Atom::Type format,
- AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
-
- // accessors
- AP4_UI16 GetWidth() { return m_Width; }
- AP4_UI16 GetHeight() { return m_Height; }
- AP4_UI16 GetHorizResolution(){ return m_HorizResolution; }
- AP4_UI16 GetVertResolution() { return m_VertResolution; }
- AP4_UI16 GetDepth() { return m_Depth; }
- const char* GetCompressorName() { return m_CompressorName.c_str(); }
-
- // methods
- AP4_SampleDescription* ToSampleDescription();
-
-protected:
- // methods
- virtual AP4_Size GetFieldsSize();
- virtual AP4_Result ReadFields(AP4_ByteStream& stream);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
-
- //members
- AP4_UI16 m_Predefined1; // = 0
- AP4_UI16 m_Reserved2; // = 0
- AP4_UI08 m_Predefined2[12]; // = 0
- AP4_UI16 m_Width;
- AP4_UI16 m_Height;
- AP4_UI32 m_HorizResolution; // = 0x00480000 (72 dpi)
- AP4_UI32 m_VertResolution; // = 0x00480000 (72 dpi)
- AP4_UI32 m_Reserved3; // = 0
- AP4_UI16 m_FrameCount; // = 1
- AP4_String m_CompressorName;
- AP4_UI16 m_Depth; // = 0x0018
- AP4_UI16 m_Predefined3; // = 0xFFFF
-};
-
-/*----------------------------------------------------------------------
-| AP4_Mp4vSampleEntry
-+---------------------------------------------------------------------*/
-class AP4_Mp4vSampleEntry : public AP4_VisualSampleEntry
-{
- public:
- // constructors
- AP4_Mp4vSampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
- AP4_Mp4vSampleEntry(AP4_UI16 width,
- AP4_UI16 height,
- AP4_UI16 depth,
- const char* compressor_name,
- AP4_EsDescriptor* descriptor);
-};
-
-/*----------------------------------------------------------------------
-| AP4_Avc1SampleEntry
-+---------------------------------------------------------------------*/
-class AP4_Avc1SampleEntry : public AP4_VisualSampleEntry
-{
-public:
- // constructors
- AP4_Avc1SampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
- AP4_Avc1SampleEntry(AP4_UI16 width,
- AP4_UI16 height,
- AP4_UI16 depth,
- const char* compressor_name,
- AP4_EsDescriptor* descriptor);
-};
-
-/*----------------------------------------------------------------------
-| AP4_RtpHintSampleEntry
-+---------------------------------------------------------------------*/
-class AP4_RtpHintSampleEntry : public AP4_SampleEntry
-{
-public:
- // methods
- AP4_RtpHintSampleEntry(AP4_UI16 hint_track_version,
- AP4_UI16 highest_compatible_version,
- AP4_UI32 max_packet_size,
- AP4_UI32 timescale);
- AP4_RtpHintSampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
- virtual ~AP4_RtpHintSampleEntry();
-
-protected:
- // methods
- virtual AP4_Size GetFieldsSize();
- virtual AP4_Result ReadFields(AP4_ByteStream& stream);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
-
- // members
- AP4_UI16 m_HintTrackVersion;
- AP4_UI16 m_HighestCompatibleVersion;
- AP4_UI32 m_MaxPacketSize;
-};
-
+/***************************************************************** +| +| AP4 - sample entries +| +| 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_SAMPLE_ENTRY_H_ +#define _AP4_SAMPLE_ENTRY_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4List.h" +#include "Ap4Atom.h" +#include "Ap4EsdsAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4ContainerAtom.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_SampleDescription; +class AP4_AvccAtom; + +/*---------------------------------------------------------------------- +| AP4_SampleEntry ++---------------------------------------------------------------------*/ +class AP4_SampleEntry : public AP4_ContainerAtom +{ + public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_SampleEntry, AP4_ContainerAtom) + + // methods + AP4_SampleEntry(AP4_Atom::Type format, AP4_UI16 data_ref_index = 1); + AP4_SampleEntry(AP4_Atom::Type format, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + AP4_UI16 GetDataReferenceIndex() { return m_DataReferenceIndex; } + virtual AP4_Result Write(AP4_ByteStream& stream); + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + virtual AP4_SampleDescription* ToSampleDescription(); + + // AP4_AtomParent methods + virtual void OnChildChanged(AP4_Atom* child); + + protected: + // constructor + AP4_SampleEntry(AP4_Atom::Type format, AP4_Size size); + + // methods + virtual AP4_Size GetFieldsSize(); + virtual AP4_Result ReadFields(AP4_ByteStream& stream); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + + // members + AP4_UI08 m_Reserved1[6]; // = 0 + AP4_UI16 m_DataReferenceIndex; +}; + +/*---------------------------------------------------------------------- +| AP4_AudioSampleEntry ++---------------------------------------------------------------------*/ +class AP4_AudioSampleEntry : public AP4_SampleEntry +{ +public: + // methods + AP4_AudioSampleEntry(AP4_Atom::Type format, + AP4_UI32 sample_rate, + AP4_UI16 sample_size, + AP4_UI16 channel_count); + AP4_AudioSampleEntry(AP4_Atom::Type format, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // accessors + AP4_UI32 GetSampleRate(); + AP4_UI16 GetSampleSize() { return m_SampleSize; } + AP4_UI16 GetChannelCount(); + // ==> Start patch MPC + AP4_UI32 GetBytesPerFrame() { return m_QtV1BytesPerFrame; }; + // <== End patch MPC + + // methods + AP4_SampleDescription* ToSampleDescription(); + + // this method is used as a factory by the ISMACryp classes + // NOTE: this should be named ToSampleDescription, but C++ has a + // problem with that because the base class does not have this + // overloaded method, but has another other one by that name + virtual AP4_SampleDescription* ToTargetSampleDescription(AP4_UI32 format); + +protected: + // methods + virtual AP4_Size GetFieldsSize(); + virtual AP4_Result ReadFields(AP4_ByteStream& stream); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + + // members + AP4_UI16 m_QtVersion; // 0, 1 or 2 + AP4_UI16 m_QtRevision; // 0 + AP4_UI32 m_QtVendor; // 0 + AP4_UI16 m_ChannelCount; + AP4_UI16 m_SampleSize; + AP4_UI16 m_QtCompressionId; // 0 or -2 + AP4_UI16 m_QtPacketSize; // always 0 + AP4_UI32 m_SampleRate; // 16.16 fixed point + + AP4_UI32 m_QtV1SamplesPerPacket; + AP4_UI32 m_QtV1BytesPerPacket; + AP4_UI32 m_QtV1BytesPerFrame; + AP4_UI32 m_QtV1BytesPerSample; + + AP4_UI32 m_QtV2StructSize; + double m_QtV2SampleRate64; + AP4_UI32 m_QtV2ChannelCount; + AP4_UI32 m_QtV2Reserved; + AP4_UI32 m_QtV2BitsPerChannel; + AP4_UI32 m_QtV2FormatSpecificFlags; + AP4_UI32 m_QtV2BytesPerAudioPacket; + AP4_UI32 m_QtV2LPCMFramesPerAudioPacket; + AP4_DataBuffer m_QtV2Extension; +}; + +/*---------------------------------------------------------------------- +| AP4_VisualSampleEntry ++---------------------------------------------------------------------*/ +class AP4_VisualSampleEntry : public AP4_SampleEntry +{ +public: + // methods + AP4_VisualSampleEntry(AP4_Atom::Type format, + AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name); + AP4_VisualSampleEntry(AP4_Atom::Type format, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // accessors + AP4_UI16 GetWidth() { return m_Width; } + AP4_UI16 GetHeight() { return m_Height; } + AP4_UI16 GetHorizResolution(){ return m_HorizResolution; } + AP4_UI16 GetVertResolution() { return m_VertResolution; } + AP4_UI16 GetDepth() { return m_Depth; } + const char* GetCompressorName() { return m_CompressorName.GetChars(); } + + // methods + AP4_SampleDescription* ToSampleDescription(); + + // this method is used as a factory by the ISMACryp classes + // NOTE: this should be named ToSampleDescription, but C++ has a + // problem with that because the base class does not have this + // overloaded method, but has another other one by that name + virtual AP4_SampleDescription* ToTargetSampleDescription(AP4_UI32 format); + +protected: + // methods + virtual AP4_Size GetFieldsSize(); + virtual AP4_Result ReadFields(AP4_ByteStream& stream); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + + //members + AP4_UI16 m_Predefined1; // = 0 + AP4_UI16 m_Reserved2; // = 0 + AP4_UI08 m_Predefined2[12]; // = 0 + AP4_UI16 m_Width; + AP4_UI16 m_Height; + AP4_UI32 m_HorizResolution; // = 0x00480000 (72 dpi) + AP4_UI32 m_VertResolution; // = 0x00480000 (72 dpi) + AP4_UI32 m_Reserved3; // = 0 + AP4_UI16 m_FrameCount; // = 1 + AP4_String m_CompressorName; + AP4_UI16 m_Depth; // = 0x0018 + AP4_UI16 m_Predefined3; // = 0xFFFF +}; + +/*---------------------------------------------------------------------- +| AP4_MpegSystemSampleEntry ++---------------------------------------------------------------------*/ +class AP4_MpegSystemSampleEntry : public AP4_SampleEntry +{ +public: + // constructors + AP4_MpegSystemSampleEntry(AP4_UI32 type, + AP4_EsDescriptor* descriptor); + AP4_MpegSystemSampleEntry(AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // methods + AP4_SampleDescription* ToSampleDescription(); +}; + +/*---------------------------------------------------------------------- +| AP4_MpegAudioSampleEntry ++---------------------------------------------------------------------*/ +class AP4_MpegAudioSampleEntry : public AP4_AudioSampleEntry +{ +public: + // constructors + AP4_MpegAudioSampleEntry(AP4_UI32 type, + AP4_UI32 sample_rate, + AP4_UI16 sample_size, + AP4_UI16 channel_count, + AP4_EsDescriptor* descriptor); + AP4_MpegAudioSampleEntry(AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // methods + AP4_SampleDescription* ToSampleDescription(); +}; + +/*---------------------------------------------------------------------- +| AP4_MpegVideoSampleEntry ++---------------------------------------------------------------------*/ +class AP4_MpegVideoSampleEntry : public AP4_VisualSampleEntry +{ +public: + // constructors + AP4_MpegVideoSampleEntry(AP4_UI32 type, + AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_EsDescriptor* descriptor); + AP4_MpegVideoSampleEntry(AP4_UI32 type, + AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // methods + AP4_SampleDescription* ToSampleDescription(); +}; + +/*---------------------------------------------------------------------- +| AP4_Mp4sSampleEntry ++---------------------------------------------------------------------*/ +class AP4_Mp4sSampleEntry : public AP4_MpegSystemSampleEntry +{ + public: + // constructors + AP4_Mp4sSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + AP4_Mp4sSampleEntry(AP4_EsDescriptor* descriptor); + + // methods + AP4_SampleDescription* ToSampleDescription(); +}; + +/*---------------------------------------------------------------------- +| AP4_Mp4aSampleEntry ++---------------------------------------------------------------------*/ +class AP4_Mp4aSampleEntry : public AP4_MpegAudioSampleEntry +{ + public: + // constructors + AP4_Mp4aSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + AP4_Mp4aSampleEntry(AP4_UI32 sample_rate, + AP4_UI16 sample_size, + AP4_UI16 channel_count, + AP4_EsDescriptor* descriptor); +}; + +/*---------------------------------------------------------------------- +| AP4_Mp4vSampleEntry ++---------------------------------------------------------------------*/ +class AP4_Mp4vSampleEntry : public AP4_MpegVideoSampleEntry +{ + public: + // constructors + AP4_Mp4vSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + AP4_Mp4vSampleEntry(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + AP4_EsDescriptor* descriptor); +}; + +/*---------------------------------------------------------------------- +| AP4_Avc1SampleEntry ++---------------------------------------------------------------------*/ +class AP4_Avc1SampleEntry : public AP4_VisualSampleEntry +{ +public: + // constructors + AP4_Avc1SampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + AP4_Avc1SampleEntry(AP4_UI16 width, + AP4_UI16 height, + AP4_UI16 depth, + const char* compressor_name, + const AP4_AvccAtom& avcc); + + // inherited from AP4_SampleEntry + virtual AP4_SampleDescription* ToSampleDescription(); +}; + +/*---------------------------------------------------------------------- +| AP4_RtpHintSampleEntry ++---------------------------------------------------------------------*/ +class AP4_RtpHintSampleEntry : public AP4_SampleEntry +{ +public: + // methods + AP4_RtpHintSampleEntry(AP4_UI16 hint_track_version, + AP4_UI16 highest_compatible_version, + AP4_UI32 max_packet_size, + AP4_UI32 timescale); + AP4_RtpHintSampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + virtual ~AP4_RtpHintSampleEntry(); + +protected: + // methods + virtual AP4_Size GetFieldsSize(); + virtual AP4_Result ReadFields(AP4_ByteStream& stream); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + + // members + AP4_UI16 m_HintTrackVersion; + AP4_UI16 m_HighestCompatibleVersion; + AP4_UI32 m_MaxPacketSize; +}; + +// ==> Start patch MPC /*----------------------------------------------------------------------
| AP4_TextSampleEntry
+---------------------------------------------------------------------*/
@@ -333,7 +397,7 @@ protected: // members
AP4_TextDescription m_Description;
};
-
+ /*----------------------------------------------------------------------
| AP4_Tx3gSampleEntry
+---------------------------------------------------------------------*/
@@ -371,6 +435,8 @@ protected: AP4_Tx3gDescription m_Description;
};
+ + /*----------------------------------------------------------------------
| AP4_AC3SampleEntry
+---------------------------------------------------------------------*/
@@ -378,12 +444,18 @@ class AP4_AC3SampleEntry : public AP4_AudioSampleEntry {
public:
// constructors
- AP4_AC3SampleEntry(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
+ AP4_AC3SampleEntry(AP4_UI32 sample_rate, + AP4_UI16 sample_size, + AP4_UI16 channel_count); + + AP4_AC3SampleEntry(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); - AP4_Result ReadFields(AP4_ByteStream& stream);
- AP4_Size GetFieldsSize();
+protected:
+ virtual AP4_Size GetFieldsSize();
+ virtual AP4_Result ReadFields(AP4_ByteStream& stream); };
-
-#endif // _AP4_SAMPLE_ENTRY_H_
+// <== End patch MPC + +#endif // _AP4_SAMPLE_ENTRY_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleTable.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleTable.cpp index 174122504..cedd1002d 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleTable.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleTable.cpp @@ -2,7 +2,7 @@ | | AP4 - Sample Table Interface | -| Copyright 2003-2004 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,7 +27,7 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4SampleTable.h" #include "Ap4ContainerAtom.h" @@ -35,79 +35,175 @@ #include "Ap4StszAtom.h" #include "Ap4StscAtom.h" #include "Ap4StcoAtom.h" +#include "Ap4Co64Atom.h" #include "Ap4SttsAtom.h" +#include "Ap4StssAtom.h" +#include "Ap4CttsAtom.h" +#include "Ap4Sample.h" /*---------------------------------------------------------------------- -| AP4_SampleTable::GenerateStblAtom +| AP4_SampleTable::GenerateStblAtom +---------------------------------------------------------------------*/ AP4_Result AP4_SampleTable::GenerateStblAtom(AP4_ContainerAtom*& stbl) { // create the stbl container - stbl = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_STBL); + stbl = new AP4_ContainerAtom(AP4_ATOM_TYPE_STBL); // create the stsd atom - AP4_StsdAtom* stsd = DNew AP4_StsdAtom(this); + AP4_StsdAtom* stsd = new AP4_StsdAtom(this); // create the stsz atom - AP4_StszAtom* stsz = DNew AP4_StszAtom(); + AP4_StszAtom* stsz = new AP4_StszAtom(); // create the stsc atom - AP4_StscAtom* stsc = DNew AP4_StscAtom(); + AP4_StscAtom* stsc = new AP4_StscAtom(); + // create the stts atom + AP4_SttsAtom* stts = new AP4_SttsAtom(); + + // create the stss atom + AP4_StssAtom* stss = new AP4_StssAtom(); + + // declare the ctts atom (may be created later) + AP4_CttsAtom* ctts = NULL; + // start chunk table - AP4_Cardinal samples_in_chunk = 0; - AP4_Offset current_chunk_offset = 0; - AP4_Size current_chunk_size = 0; - AP4_Array<AP4_UI32> chunk_offsets; + AP4_Ordinal current_chunk_index = 0; + AP4_Size current_chunk_size = 0; + AP4_Position current_chunk_offset = 0; + AP4_Cardinal current_samples_in_chunk = 0; + AP4_Ordinal current_sample_description_index = 0; + AP4_UI32 current_duration = 0; + AP4_Cardinal current_duration_run = 0; + AP4_UI32 current_cts_delta = 0; + AP4_Cardinal current_cts_delta_run = 0; + AP4_Array<AP4_Position> chunk_offsets; // process all the samples + bool all_samples_are_sync = false; AP4_Cardinal sample_count = GetSampleCount(); for (AP4_Ordinal i=0; i<sample_count; i++) { AP4_Sample sample; GetSample(i, sample); + // update DTS table + AP4_UI32 new_duration = sample.GetDuration(); + if (new_duration != current_duration && current_duration_run != 0) { + // emit a new stts entry + stts->AddEntry(current_duration_run, current_duration); + + // reset the run count + current_duration_run = 0; + } + ++current_duration_run; + current_duration = new_duration; + + // update CTS table + AP4_UI32 new_cts_delta = sample.GetCtsDelta(); + if (new_cts_delta != current_cts_delta && current_cts_delta_run != 0) { + // create a ctts atom if we don't have one + if (ctts == NULL) ctts = new AP4_CttsAtom(); + + //emit a new ctts entry + ctts->AddEntry(current_cts_delta_run, current_cts_delta); + + // reset the run count + current_cts_delta_run = 0; + } + ++current_cts_delta_run; + current_cts_delta = new_cts_delta; + + // store the sample description index + current_sample_description_index = sample.GetDescriptionIndex(); + // add an entry into the stsz atom stsz->AddEntry(sample.GetSize()); - // adjust the current chunk info - current_chunk_size += sample.GetSize(); + // update the sync sample table + if (sample.IsSync()) { + stss->AddEntry(i+1); + if (i==0) all_samples_are_sync = true; + } else { + all_samples_are_sync = false; + } + + // see in which chunk this sample is + AP4_Ordinal chunk_index = 0; + AP4_Ordinal position_in_chunk = 0; + AP4_Result result = GetSampleChunkPosition(i, chunk_index, position_in_chunk); + if (AP4_SUCCEEDED(result)) { + if (chunk_index != current_chunk_index && current_samples_in_chunk != 0) { + // new chunk + chunk_offsets.Append(current_chunk_offset); + current_chunk_offset += current_chunk_size; - // count the sample - samples_in_chunk++; - if (samples_in_chunk == 10) { - // new chunk - chunk_offsets.Append(current_chunk_offset); - stsc->AddEntry(1, 10, 1); - samples_in_chunk = 0; - - // adjust the chunk offset - current_chunk_offset += current_chunk_size; - current_chunk_size = 0; + stsc->AddEntry(1, + current_samples_in_chunk, + current_sample_description_index+1); + + current_samples_in_chunk = 0; + current_chunk_size = 0; + } + current_chunk_index = chunk_index; } + + // adjust the current chunk info + current_chunk_size += sample.GetSize(); + ++current_samples_in_chunk; } + // finish the stts table + stts->AddEntry(current_duration_run, current_duration); + + // finish the ctts table if we have one + if (ctts) { + AP4_ASSERT(current_cts_delta_run != 0); + + // add a ctts entry + ctts->AddEntry(current_cts_delta_run, current_cts_delta); + } + // process any unfinished chunk - if (samples_in_chunk != 0) { + if (current_samples_in_chunk != 0) { // new chunk chunk_offsets.Append(current_chunk_offset); - stsc->AddEntry(1, samples_in_chunk, 1); + stsc->AddEntry(1, + current_samples_in_chunk, + current_sample_description_index+1); } - // create the stco atom - AP4_StcoAtom* stco = DNew AP4_StcoAtom(&chunk_offsets[0], - chunk_offsets.ItemCount()); - - // create the stts atom (for now, we assume sample of equal duration) - AP4_SttsAtom* stts = DNew AP4_SttsAtom(); - stts->AddEntry(sample_count, 1000); // FIXME - // attach the children of stbl stbl->AddChild(stsd); stbl->AddChild(stsz); stbl->AddChild(stsc); - stbl->AddChild(stco); stbl->AddChild(stts); + if (ctts) stbl->AddChild(ctts); + if (!all_samples_are_sync && stss->GetEntries().ItemCount() != 0) { + stbl->AddChild(stss); + } else { + delete stss; + } + + // see if we need a co64 or an stco atom + AP4_Size chunk_count = chunk_offsets.ItemCount(); + if (current_chunk_offset <= 0xFFFFFFFF) { + // make an array of 32-bit entries + AP4_UI32* chunk_offsets_32 = new AP4_UI32[chunk_count]; + for (unsigned int i=0; i<chunk_count; i++) { + chunk_offsets_32[i] = (AP4_UI32)chunk_offsets[i]; + } + // create the stco atom + AP4_StcoAtom* stco = new AP4_StcoAtom(&chunk_offsets_32[0], chunk_count); + stbl->AddChild(stco); + + delete[] chunk_offsets_32; + } else { + // create the co64 atom + AP4_Co64Atom* co64 = new AP4_Co64Atom(&chunk_offsets[0], chunk_count); + stbl->AddChild(co64); + } + return AP4_SUCCESS; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleTable.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleTable.h index 55f97a1b6..45a6c7bb0 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleTable.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SampleTable.h @@ -2,7 +2,7 @@ | | AP4 - Sample Table Interface | -| Copyright 2003-2004 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,15 +30,19 @@ #define _AP4_SAMPLE_TABLE_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4Sample.h" -#include "Ap4Atom.h" -#include "Ap4ContainerAtom.h" -#include "Ap4SampleDescription.h" +#include "Ap4Types.h" /*---------------------------------------------------------------------- -| AP4_SampleTable +| class references ++---------------------------------------------------------------------*/ +class AP4_Sample; +class AP4_ContainerAtom; +class AP4_SampleDescription; + +/*---------------------------------------------------------------------- +| AP4_SampleTable +---------------------------------------------------------------------*/ class AP4_SampleTable { public: @@ -46,13 +50,17 @@ public: virtual ~AP4_SampleTable() {}; // methods - virtual AP4_Result GenerateStblAtom(AP4_ContainerAtom*& stbl); - virtual AP4_Result GetSample(AP4_Ordinal index, AP4_Sample& sample) = 0; + virtual AP4_Result GenerateStblAtom(AP4_ContainerAtom*& stbl); + virtual AP4_Result GetSample(AP4_Ordinal sample_index, AP4_Sample& sample) = 0; virtual AP4_Cardinal GetSampleCount() = 0; + virtual AP4_Result GetSampleChunkPosition(AP4_Ordinal sample_index, + AP4_Ordinal& chunk_index, + AP4_Ordinal& position_in_chunk) = 0; virtual AP4_Cardinal GetSampleDescriptionCount() = 0; virtual AP4_SampleDescription* GetSampleDescription(AP4_Ordinal index) = 0; - virtual AP4_Result GetSampleIndexForTimeStamp(AP4_TimeStamp ts, - AP4_Ordinal& index) = 0; + virtual AP4_Result GetSampleIndexForTimeStamp(AP4_UI64 ts, + AP4_Ordinal& index) = 0; + virtual AP4_Ordinal GetNearestSyncSampleIndex(AP4_Ordinal index, bool before=true) = 0; }; #endif // _AP4_SAMPLE_TABLE_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SchmAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SchmAtom.cpp index f0b3ff69b..767e59368 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SchmAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SchmAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - schm Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,42 +27,87 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4SchmAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_SchmAtom::AP4_SchmAtom +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_SchmAtom) + +/*---------------------------------------------------------------------- +| AP4_SchmAtom::Create ++---------------------------------------------------------------------*/ +AP4_SchmAtom* +AP4_SchmAtom::Create(AP4_Size size, + AP4_Array<AP4_Atom::Type>* context, + 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 < AP4_FULL_ATOM_HEADER_SIZE+6) return NULL; + + // check the context to see if this is a short form atom or not + bool short_form = false; + if (size < AP4_FULL_ATOM_HEADER_SIZE+8) short_form = true; + if (context) { + AP4_Size context_depth = context->ItemCount(); + if (context_depth >= 2 && + (*context)[context_depth-2] == AP4_ATOM_TYPE('m','r','l','n')) { + short_form = true; + } + } + + return new AP4_SchmAtom(size, version, flags, short_form, stream); +} + +/*---------------------------------------------------------------------- +| AP4_SchmAtom::AP4_SchmAtom +---------------------------------------------------------------------*/ AP4_SchmAtom::AP4_SchmAtom(AP4_UI32 scheme_type, AP4_UI32 scheme_version, - const char* scheme_uri) : - AP4_Atom(AP4_ATOM_TYPE_SCHM, AP4_FULL_ATOM_HEADER_SIZE+8, true), + const char* scheme_uri, + bool short_form) : + AP4_Atom(AP4_ATOM_TYPE_SCHM, AP4_FULL_ATOM_HEADER_SIZE+4+(short_form?2:4), 0, 0), + m_AtomHasShortForm(short_form), m_SchemeType(scheme_type), m_SchemeVersion(scheme_version) { if (scheme_uri) { m_SchemeUri = scheme_uri; m_Flags = 1; - m_Size += m_SchemeUri.length()+1; + m_Size32 += m_SchemeUri.GetLength()+1; } } /*---------------------------------------------------------------------- -| AP4_SchmAtom::AP4_SchmAtom +| AP4_SchmAtom::AP4_SchmAtom +---------------------------------------------------------------------*/ -AP4_SchmAtom::AP4_SchmAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_SCHM, size, true, stream) +AP4_SchmAtom::AP4_SchmAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + bool short_form, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_SCHM, size, version, flags), + m_AtomHasShortForm(short_form) { stream.ReadUI32(m_SchemeType); - stream.ReadUI32(m_SchemeVersion); + if (short_form) { + AP4_UI16 short_version; + stream.ReadUI16(short_version); + m_SchemeVersion = short_version; + } else { + stream.ReadUI32(m_SchemeVersion); + } if (m_Flags & 1) { int str_size = size-(AP4_FULL_ATOM_HEADER_SIZE+8); if (str_size > 0) { - char* str = DNew char[str_size]; + char* str = new char[str_size]; stream.Read(str, str_size); str[str_size-1] = '\0'; // force null-termination m_SchemeUri = str; @@ -72,7 +117,7 @@ AP4_SchmAtom::AP4_SchmAtom(AP4_Size size, AP4_ByteStream& stream) : } /*---------------------------------------------------------------------- -| AP4_SchmAtom::WriteFields +| AP4_SchmAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_SchmAtom::WriteFields(AP4_ByteStream& stream) @@ -84,26 +129,30 @@ AP4_SchmAtom::WriteFields(AP4_ByteStream& stream) if (AP4_FAILED(result)) return result; // scheme version - result = stream.WriteUI32(m_SchemeVersion); - if (AP4_FAILED(result)) return result; - + if (m_AtomHasShortForm) { + result = stream.WriteUI16((AP4_UI16)m_SchemeVersion); + if (AP4_FAILED(result)) return result; + } else { + result = stream.WriteUI32(m_SchemeVersion); + if (AP4_FAILED(result)) return result; + } + // uri if needed if (m_Flags & 1) { - result = stream.Write(m_SchemeUri.c_str(), m_SchemeUri.length()+1); + result = stream.Write(m_SchemeUri.GetChars(), m_SchemeUri.GetLength()+1); if (AP4_FAILED(result)) return result; // pad with zeros if necessary - AP4_Size padding = m_Size-(AP4_FULL_ATOM_HEADER_SIZE+8+m_SchemeUri.length()+1); - while (padding--) { - stream.WriteUI08(0); - } + AP4_Size fields_size = 4+(m_AtomHasShortForm?2:4); + AP4_Size padding = m_Size32-(AP4_FULL_ATOM_HEADER_SIZE+fields_size+m_SchemeUri.GetLength()+1); + while (padding--) stream.WriteUI08(0); } return result; } /*---------------------------------------------------------------------- -| AP4_SchmAtom::InspectFields +| AP4_SchmAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_SchmAtom::InspectFields(AP4_AtomInspector& inspector) @@ -111,9 +160,13 @@ AP4_SchmAtom::InspectFields(AP4_AtomInspector& inspector) char st[5]; AP4_FormatFourChars(st, m_SchemeType); inspector.AddField("scheme_type", st); - inspector.AddField("scheme_version", m_SchemeVersion); + if (m_AtomHasShortForm) { + inspector.AddField("scheme_version (short)", m_SchemeVersion); + } else { + inspector.AddField("scheme_version", m_SchemeVersion); + } if (m_Flags & 1) { - inspector.AddField("scheme_uri", m_SchemeUri.c_str()); + inspector.AddField("scheme_uri", m_SchemeUri.GetChars()); } return AP4_SUCCESS; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SchmAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SchmAtom.h index d5149fa1c..3b2a065db 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SchmAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SchmAtom.h @@ -2,7 +2,7 @@ | | AP4 - schm Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,24 +30,36 @@ #define _AP4_SCHM_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4Array.h" +#include "Ap4Types.h" +#include "Ap4String.h" #include "Ap4Atom.h" +#include "Ap4Array.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; /*---------------------------------------------------------------------- -| AP4_SchmAtom +| AP4_SchmAtom +---------------------------------------------------------------------*/ class AP4_SchmAtom : public AP4_Atom { - public: +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_SchmAtom, AP4_Atom) + + // class methods + static AP4_SchmAtom* Create(AP4_Size size, + AP4_Array<AP4_Atom::Type>* context, + AP4_ByteStream& stream); + // constructors AP4_SchmAtom(AP4_UI32 scheme_type, AP4_UI32 scheme_version, - const char* scheme_uri = NULL); - AP4_SchmAtom(AP4_Size size, AP4_ByteStream& stream); + const char* scheme_uri = NULL, + bool short_form = false); // methods virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); @@ -58,8 +70,17 @@ class AP4_SchmAtom : public AP4_Atom AP4_UI32 GetSchemeVersion() { return m_SchemeVersion; } AP4_String& GetSchemeUri() { return m_SchemeUri; } - private: +private: + // methods + AP4_SchmAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + bool short_form, + AP4_ByteStream& stream); + // members + bool m_AtomHasShortForm; // for versions of this where the version + // field is only 16 bits AP4_UI32 m_SchemeType; AP4_UI32 m_SchemeVersion; AP4_String m_SchemeUri; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SdpAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SdpAtom.cpp index fe086b895..56237781e 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SdpAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SdpAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - sdp Atoms | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,34 +27,33 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4SdpAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_SdpAtom::AP4_SdpAtom +| AP4_SdpAtom::AP4_SdpAtom +---------------------------------------------------------------------*/ AP4_SdpAtom::AP4_SdpAtom(const char* sdp_text) : - AP4_Atom(AP4_ATOM_TYPE_SDP, AP4_ATOM_HEADER_SIZE, false), + AP4_Atom(AP4_ATOM_TYPE_SDP_, AP4_ATOM_HEADER_SIZE), m_SdpText(sdp_text) { - m_Size += m_SdpText.length()+1; + m_Size32 += m_SdpText.GetLength()+1; } /*---------------------------------------------------------------------- -| AP4_SdpAtom::AP4_SdpAtom +| AP4_SdpAtom::AP4_SdpAtom +---------------------------------------------------------------------*/ -AP4_SdpAtom::AP4_SdpAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_SDP, size, false, stream) +AP4_SdpAtom::AP4_SdpAtom(AP4_UI32 size, AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_SDP_, size) { // sdptext AP4_Size str_size = size-AP4_ATOM_HEADER_SIZE; if (str_size > 0) { - char* str = DNew char[str_size+1]; + char* str = new char[str_size+1]; stream.Read(str, str_size); str[str_size] = '\0'; // force null-termination m_SdpText = str; @@ -63,35 +62,35 @@ AP4_SdpAtom::AP4_SdpAtom(AP4_Size size, AP4_ByteStream& stream) : } /*---------------------------------------------------------------------- -| AP4_SdpAtom::WriteFields +| AP4_SdpAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_SdpAtom::WriteFields(AP4_ByteStream& stream) { // sdptext - AP4_Result result = stream.Write(m_SdpText.c_str(), m_SdpText.length()); + AP4_Result result = stream.Write(m_SdpText.GetChars(), m_SdpText.GetLength()); if (AP4_FAILED(result)) return result; // pad with zeros if necessary - AP4_Size padding = m_Size-(AP4_ATOM_HEADER_SIZE+m_SdpText.length()); + AP4_Size padding = m_Size32-(AP4_ATOM_HEADER_SIZE+m_SdpText.GetLength()); while (padding--) stream.WriteUI08(0); return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_SdpAtom::InspectFields +| AP4_SdpAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_SdpAtom::InspectFields(AP4_AtomInspector& inspector) { - inspector.AddField("sdp_text", m_SdpText.c_str()); + inspector.AddField("sdp_text", m_SdpText.GetChars()); return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_SdpAtom::GetSdpText +| AP4_SdpAtom::GetSdpText +---------------------------------------------------------------------*/ const AP4_String& AP4_SdpAtom::GetSdpText() const diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SdpAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SdpAtom.h index 5ed54c9c2..421a73b12 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SdpAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SdpAtom.h @@ -2,7 +2,7 @@ | | AP4 - sdp Atoms | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,22 +30,29 @@ #define _AP4_SDP_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" #include "Ap4List.h" #include "Ap4Atom.h" -#include "Ap4DataBuffer.h" +#include "Ap4String.h" /*---------------------------------------------------------------------- -| AP4_SdpAtom +| class references ++---------------------------------------------------------------------*/ +class AP4_ByteStream; + +/*---------------------------------------------------------------------- +| AP4_SdpAtom +---------------------------------------------------------------------*/ class AP4_SdpAtom : public AP4_Atom { public: + // class methods + static AP4_SdpAtom* Create(AP4_Size size, AP4_ByteStream& stream) { + return new AP4_SdpAtom(size, stream); + } + // methods - AP4_SdpAtom(AP4_Size size, AP4_ByteStream& stream); AP4_SdpAtom(const char* sdp_text); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); @@ -54,6 +61,9 @@ public: const AP4_String& GetSdpText() const; private: + // methods + AP4_SdpAtom(AP4_UI32 size, AP4_ByteStream& stream); + // members AP4_String m_SdpText; }; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SmhdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SmhdAtom.cpp index 6aa5f7b58..88052ced1 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SmhdAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SmhdAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - smhd Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,35 +27,50 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4SmhdAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_SmhdAtom::AP4_SmhdAtom +| AP4_SmhdAtom::Create ++---------------------------------------------------------------------*/ +AP4_SmhdAtom* +AP4_SmhdAtom::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_SmhdAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_SmhdAtom::AP4_SmhdAtom +---------------------------------------------------------------------*/ AP4_SmhdAtom::AP4_SmhdAtom(AP4_UI16 balance) : - AP4_Atom(AP4_ATOM_TYPE_SMHD, 4+AP4_FULL_ATOM_HEADER_SIZE, true), + AP4_Atom(AP4_ATOM_TYPE_SMHD, AP4_FULL_ATOM_HEADER_SIZE+4, 0, 0), m_Balance(balance) { m_Reserved = 0; } /*---------------------------------------------------------------------- -| AP4_SmhdAtom::AP4_SmhdAtom +| AP4_SmhdAtom::AP4_SmhdAtom +---------------------------------------------------------------------*/ -AP4_SmhdAtom::AP4_SmhdAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_SMHD, size, true, stream) +AP4_SmhdAtom::AP4_SmhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_SMHD, size, version, flags) { stream.ReadUI16(m_Balance); stream.ReadUI16(m_Reserved); } /*---------------------------------------------------------------------- -| AP4_SmhdAtom::WriteFields +| AP4_SmhdAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_SmhdAtom::WriteFields(AP4_ByteStream& stream) @@ -74,7 +89,7 @@ AP4_SmhdAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_SmhdAtom::InspectFields +| AP4_SmhdAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_SmhdAtom::InspectFields(AP4_AtomInspector& inspector) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SmhdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SmhdAtom.h index eaabb8458..8d6269b5b 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SmhdAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SmhdAtom.h @@ -2,7 +2,7 @@ | | AP4 - smhd Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,25 +30,32 @@ #define _AP4_SMHD_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" +#include "Ap4Types.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_SmhdAtom +| AP4_SmhdAtom +---------------------------------------------------------------------*/ class AP4_SmhdAtom : public AP4_Atom { public: + // class methods + static AP4_SmhdAtom* Create(AP4_Size size, AP4_ByteStream& stream); + // methods AP4_SmhdAtom(AP4_UI16 balance); - AP4_SmhdAtom(AP4_Size size, AP4_ByteStream& stream); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); private: + // methods + AP4_SmhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + // members AP4_UI16 m_Balance; AP4_UI16 m_Reserved; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StcoAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StcoAtom.cpp index 4875f5043..4ed8fe1f3 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StcoAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StcoAtom.cpp @@ -1,152 +1,185 @@ -/*****************************************************************
-|
-| AP4 - stco Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4StcoAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_StcoAtom::AP4_StcoAtom
-+---------------------------------------------------------------------*/
-AP4_StcoAtom::AP4_StcoAtom(AP4_UI32* entries, AP4_UI32 entry_count) :
-AP4_Atom(AP4_ATOM_TYPE_STCO,
- AP4_FULL_ATOM_HEADER_SIZE+4+entry_count*4,
- true),
- m_Entries(DNew AP4_UI32[entry_count]),
- m_EntryCount(entry_count)
-{
- memcpy(m_Entries, entries, m_EntryCount*4);
-}
-
-/*----------------------------------------------------------------------
-| AP4_StcoAtom::AP4_StcoAtom
-+---------------------------------------------------------------------*/
-AP4_StcoAtom::AP4_StcoAtom(AP4_Size size, AP4_ByteStream& stream) :
- AP4_Atom(AP4_ATOM_TYPE_STCO, size, true, stream)
-{
- stream.ReadUI32(m_EntryCount);
- if (m_EntryCount > (size-AP4_FULL_ATOM_HEADER_SIZE-4)/4) {
- m_EntryCount = (size-AP4_FULL_ATOM_HEADER_SIZE-4)/4;
- }
- m_Entries = DNew AP4_UI32[m_EntryCount];
- for (AP4_Ordinal i=0; i<m_EntryCount; i++) {
- stream.ReadUI32(m_Entries[i]);
- i = i;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_StcoAtom::~AP4_StcoAtom
-+---------------------------------------------------------------------*/
-AP4_StcoAtom::~AP4_StcoAtom()
-{
- delete[] m_Entries;
-}
-
-/*----------------------------------------------------------------------
-| AP4_StcoAtom::GetChunkOffset
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StcoAtom::GetChunkOffset(AP4_Ordinal chunk, AP4_Offset& chunk_offset)
-{
- // check the bounds
- if (chunk > m_EntryCount || chunk == 0) {
- return AP4_ERROR_OUT_OF_RANGE;
- }
-
- // get the chunk offset
- chunk_offset = m_Entries[chunk - 1]; // m_Entries is zero index based
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_StcoAtom::SetChunkOffset
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StcoAtom::SetChunkOffset(AP4_Ordinal chunk, AP4_Offset chunk_offset)
-{
- // check the bounds
- if (chunk > m_EntryCount || chunk == 0) {
- return AP4_ERROR_OUT_OF_RANGE;
- }
-
- // get the chunk offset
- m_Entries[chunk - 1] = chunk_offset; // m_Entries is zero index based
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_StcoAtom::AdjustChunkOffsets
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StcoAtom::AdjustChunkOffsets(AP4_Offset offset)
-{
- for (AP4_Ordinal i=0; i<m_EntryCount; i++) {
- m_Entries[i] += offset;
- }
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_StcoAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StcoAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // entry count
- result = stream.WriteUI32(m_EntryCount);
- if (AP4_FAILED(result)) return result;
-
- // entries
- for (AP4_Ordinal i=0; i<m_EntryCount; i++) {
- result = stream.WriteUI32(m_Entries[i]);
- if (AP4_FAILED(result)) return result;
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_StcoAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StcoAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("entry_count", m_EntryCount);
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - stco 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 "Ap4StcoAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_StcoAtom) + +/*---------------------------------------------------------------------- +| AP4_StcoAtom::Create ++---------------------------------------------------------------------*/ +AP4_StcoAtom* +AP4_StcoAtom::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_StcoAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_StcoAtom::AP4_StcoAtom ++---------------------------------------------------------------------*/ +AP4_StcoAtom::AP4_StcoAtom(AP4_UI32* entries, AP4_UI32 entry_count) : +AP4_Atom(AP4_ATOM_TYPE_STCO, + AP4_FULL_ATOM_HEADER_SIZE+4+entry_count*4, + 0, 0), + m_Entries(new AP4_UI32[entry_count]), + m_EntryCount(entry_count) +{ + AP4_CopyMemory(m_Entries, entries, m_EntryCount*4); +} + +/*---------------------------------------------------------------------- +| AP4_StcoAtom::AP4_StcoAtom ++---------------------------------------------------------------------*/ +AP4_StcoAtom::AP4_StcoAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_STCO, size, version, flags) +{ + stream.ReadUI32(m_EntryCount); + if (m_EntryCount > (size-AP4_FULL_ATOM_HEADER_SIZE-4)/4) { + m_EntryCount = (size-AP4_FULL_ATOM_HEADER_SIZE-4)/4; + } + m_Entries = new AP4_UI32[m_EntryCount]; + unsigned char* buffer = new unsigned char[m_EntryCount*4]; + AP4_Result result = stream.Read(buffer, m_EntryCount*4); + if (AP4_FAILED(result)) { + delete[] buffer; + return; + } + for (AP4_Ordinal i=0; i<m_EntryCount; i++) { + m_Entries[i] = AP4_BytesToUInt32BE(&buffer[i*4]); + } + delete[] buffer; +} + +/*---------------------------------------------------------------------- +| AP4_StcoAtom::~AP4_StcoAtom ++---------------------------------------------------------------------*/ +AP4_StcoAtom::~AP4_StcoAtom() +{ + delete[] m_Entries; +} + +/*---------------------------------------------------------------------- +| AP4_StcoAtom::GetChunkOffset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StcoAtom::GetChunkOffset(AP4_Ordinal chunk, AP4_UI32& chunk_offset) +{ + // check the bounds + if (chunk > m_EntryCount || chunk == 0) { + return AP4_ERROR_OUT_OF_RANGE; + } + + // get the chunk offset + chunk_offset = m_Entries[chunk - 1]; // m_Entries is zero index based + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_StcoAtom::SetChunkOffset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StcoAtom::SetChunkOffset(AP4_Ordinal chunk, AP4_UI32 chunk_offset) +{ + // check the bounds + if (chunk > m_EntryCount || chunk == 0) { + return AP4_ERROR_OUT_OF_RANGE; + } + + // get the chunk offset + m_Entries[chunk - 1] = chunk_offset; // m_Entries is zero index based + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_StcoAtom::AdjustChunkOffsets ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StcoAtom::AdjustChunkOffsets(int delta) +{ + for (AP4_Ordinal i=0; i<m_EntryCount; i++) { + m_Entries[i] += delta; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_StcoAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StcoAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // entry count + result = stream.WriteUI32(m_EntryCount); + if (AP4_FAILED(result)) return result; + + // entries + for (AP4_Ordinal i=0; i<m_EntryCount; i++) { + result = stream.WriteUI32(m_Entries[i]); + if (AP4_FAILED(result)) return result; + } + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_StcoAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StcoAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("entry_count", m_EntryCount); + if (inspector.GetVerbosity() >= 1) { + char header[32]; + for (AP4_Ordinal i=0; i<m_EntryCount; i++) { + AP4_FormatString(header, sizeof(header), "entry %8d", i); + inspector.AddField(header, m_Entries[i]); + } + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StcoAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StcoAtom.h index 7d34c932f..7fdaea4cc 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StcoAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StcoAtom.h @@ -2,7 +2,7 @@ | | AP4 - stco Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,31 +30,41 @@ #define _AP4_STCO_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4Array.h" +#include "Ap4Types.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_StcoAtom +| AP4_StcoAtom +---------------------------------------------------------------------*/ class AP4_StcoAtom : public AP4_Atom { - public: +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_StcoAtom, AP4_Atom) + + // class methods + static AP4_StcoAtom* Create(AP4_Size size, AP4_ByteStream& stream); + // methods AP4_StcoAtom(AP4_UI32* offsets, AP4_UI32 offset_count); - AP4_StcoAtom(AP4_Size size, AP4_ByteStream& stream); ~AP4_StcoAtom(); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); - AP4_Cardinal GetChunkCount() { return m_EntryCount; } - AP4_Result GetChunkOffset(AP4_Ordinal chunk, AP4_Offset& chunk_offset); - AP4_Result SetChunkOffset(AP4_Ordinal chunk, AP4_Offset chunk_offset); - AP4_Result AdjustChunkOffsets(AP4_Offset offset); + AP4_Cardinal GetChunkCount() { return m_EntryCount; } + AP4_UI32* GetChunkOffsets() { return m_Entries; } + AP4_Result GetChunkOffset(AP4_Ordinal chunk, AP4_UI32& chunk_offset); + AP4_Result SetChunkOffset(AP4_Ordinal chunk, AP4_UI32 chunk_offset); + AP4_Result AdjustChunkOffsets(int delta); + +private: + // methods + AP4_StcoAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); - private: + // members AP4_UI32* m_Entries; AP4_UI32 m_EntryCount; }; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StscAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StscAtom.cpp index ce3101f02..7e108f285 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StscAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StscAtom.cpp @@ -1,8 +1,8 @@ -/***************************************************************** + /***************************************************************** | | AP4 - stsc Atoms | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,57 +27,79 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4StscAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_StscAtom::AP4_StscAtom +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_StscAtom) + +/*---------------------------------------------------------------------- +| AP4_StscAtom::Create ++---------------------------------------------------------------------*/ +AP4_StscAtom* +AP4_StscAtom::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_StscAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_StscAtom::AP4_StscAtom +---------------------------------------------------------------------*/ AP4_StscAtom::AP4_StscAtom() : - AP4_Atom(AP4_ATOM_TYPE_STSC, 4+AP4_FULL_ATOM_HEADER_SIZE, true), + AP4_Atom(AP4_ATOM_TYPE_STSC, AP4_FULL_ATOM_HEADER_SIZE+4, 0, 0), m_CachedChunkGroup(0) { } /*---------------------------------------------------------------------- -| AP4_StscAtom::AP4_StscAtom +| AP4_StscAtom::AP4_StscAtom +---------------------------------------------------------------------*/ -AP4_StscAtom::AP4_StscAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_STSC, size, true, stream), +AP4_StscAtom::AP4_StscAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_STSC, size, version, flags), m_CachedChunkGroup(0) { AP4_UI32 first_sample = 1; AP4_UI32 entry_count; stream.ReadUI32(entry_count); - while (entry_count--) { - AP4_UI32 first_chunk; - AP4_UI32 samples_per_chunk; - AP4_UI32 sample_description_index; - if (stream.ReadUI32(first_chunk) == AP4_SUCCESS && - stream.ReadUI32(samples_per_chunk) == AP4_SUCCESS && - stream.ReadUI32(sample_description_index) == AP4_SUCCESS) { - if (m_Entries.ItemCount() != 0) { - AP4_Ordinal prev = m_Entries.ItemCount()-1; - m_Entries[prev].m_ChunkCount = - first_chunk-m_Entries[prev].m_FirstChunk; - first_sample += - m_Entries[prev].m_ChunkCount * - m_Entries[prev].m_SamplesPerChunk; - } - m_Entries.Append(AP4_StscTableEntry(first_chunk, - first_sample, - samples_per_chunk, - sample_description_index)); + m_Entries.SetItemCount(entry_count); + unsigned char* buffer = new unsigned char[entry_count*12]; + AP4_Result result = stream.Read(buffer, entry_count*12); + if (AP4_FAILED(result)) { + delete[] buffer; + return; + } + for (unsigned int i=0; i<entry_count; i++) { + AP4_UI32 first_chunk = AP4_BytesToUInt32BE(&buffer[i*12 ]); + AP4_UI32 samples_per_chunk = AP4_BytesToUInt32BE(&buffer[i*12+4]); + AP4_UI32 sample_description_index = AP4_BytesToUInt32BE(&buffer[i*12+8]); + if (i) { + AP4_Ordinal prev = i-1; + m_Entries[prev].m_ChunkCount = first_chunk-m_Entries[prev].m_FirstChunk; + first_sample += m_Entries[prev].m_ChunkCount * m_Entries[prev].m_SamplesPerChunk; } + m_Entries[i].m_ChunkCount = 0; // not known yet + m_Entries[i].m_FirstChunk = first_chunk; + m_Entries[i].m_FirstSample = first_sample; + m_Entries[i].m_SamplesPerChunk = samples_per_chunk; + m_Entries[i].m_SampleDescriptionIndex = sample_description_index; } + delete[] buffer; } /*---------------------------------------------------------------------- -| AP4_StscAtom::WriteFields +| AP4_StscAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_StscAtom::WriteFields(AP4_ByteStream& stream) @@ -102,7 +124,7 @@ AP4_StscAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_StscAtom::AddEntry +| AP4_StscAtom::AddEntry +---------------------------------------------------------------------*/ AP4_Result AP4_StscAtom::AddEntry(AP4_Cardinal chunk_count, @@ -126,19 +148,19 @@ AP4_StscAtom::AddEntry(AP4_Cardinal chunk_count, m_Entries.Append(AP4_StscTableEntry(first_chunk, first_sample, chunk_count, samples_per_chunk, sample_description_index)); // update the atom size - m_Size += 12; + m_Size32 += 12; return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_StscAtom::GetChunkForSample +| AP4_StscAtom::GetChunkForSample +---------------------------------------------------------------------*/ AP4_Result AP4_StscAtom::GetChunkForSample(AP4_Ordinal sample, AP4_Ordinal& chunk, AP4_Ordinal& skip, - AP4_Ordinal& sample_description) + AP4_Ordinal& sample_description_index) { // preconditions AP4_ASSERT(sample > 0); @@ -184,10 +206,10 @@ AP4_StscAtom::GetChunkForSample(AP4_Ordinal sample, skip = sample - (m_Entries[group].m_FirstSample + m_Entries[group].m_SamplesPerChunk*chunk_offset); - sample_description = m_Entries[group].m_SampleDescriptionIndex; + sample_description_index = m_Entries[group].m_SampleDescriptionIndex; // cache the result (to accelerate finding the right group - // next time around + // next time around) m_CachedChunkGroup = group; return AP4_SUCCESS; @@ -196,12 +218,12 @@ AP4_StscAtom::GetChunkForSample(AP4_Ordinal sample, // chunk not found chunk = 0; skip = 0; - sample_description = 0; + sample_description_index = 0; return AP4_ERROR_OUT_OF_RANGE; } /*---------------------------------------------------------------------- -| AP4_StscAtom::InspectFields +| AP4_StscAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_StscAtom::InspectFields(AP4_AtomInspector& inspector) @@ -209,16 +231,22 @@ AP4_StscAtom::InspectFields(AP4_AtomInspector& inspector) inspector.AddField("entry_count", m_Entries.ItemCount()); // dump table entries - //for (unsigned int i=0; i<m_Entries.GetItemCount(); i++) { - // char dump[256]; - // sprintf(dump, " f=%ld, spc=%ld, sdi=%ld\n", - // m_Entries[i].m_FirstChunk, - // m_Entries[i].m_SamplesPerChunk, - // m_Entries[i].m_SampleDescriptionIndex); - // stream.WriteString(prefix); - // stream.WriteString(dump); - //} - + if (inspector.GetVerbosity() >= 1) { + char header[32]; + char value[256]; + for (unsigned int i=0; i<m_Entries.ItemCount(); i++) { + AP4_FormatString(header, sizeof(header), "entry %8d", i); + AP4_FormatString(value, sizeof(value), + "first_chunk=%d, first_sample*=%d, chunk_count*=%d, samples_per_chunk=%d, sample_desc_index=%d", + m_Entries[i].m_FirstChunk, + m_Entries[i].m_FirstSample, + m_Entries[i].m_ChunkCount, + m_Entries[i].m_SamplesPerChunk, + m_Entries[i].m_SampleDescriptionIndex); + inspector.AddField(header, value); + } + } + return AP4_SUCCESS; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StscAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StscAtom.h index 09d4b905d..70a63b96d 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StscAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StscAtom.h @@ -1,105 +1,111 @@ -/*****************************************************************
-|
-| AP4 - stsc Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_STSC_ATOM_H_
-#define _AP4_STSC_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4Array.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| AP4_StscTableEntry
-+---------------------------------------------------------------------*/
-class AP4_StscTableEntry {
- public:
- AP4_StscTableEntry() :
- m_FirstChunk(0),
- m_FirstSample(0),
- m_ChunkCount(0),
- m_SamplesPerChunk(0),
- m_SampleDescriptionIndex(0) {}
- AP4_StscTableEntry(AP4_Ordinal first_chunk,
- AP4_Ordinal first_sample,
- AP4_Cardinal samples_per_chunk,
- AP4_Ordinal sample_description_index) :
- m_FirstChunk(first_chunk),
- m_FirstSample(first_sample),
- m_ChunkCount(0),
- m_SamplesPerChunk(samples_per_chunk),
- m_SampleDescriptionIndex(sample_description_index) {}
- AP4_StscTableEntry(AP4_Ordinal first_chunk,
- AP4_Ordinal first_sample,
- AP4_Cardinal chunk_count,
- AP4_Cardinal samples_per_chunk,
- AP4_Ordinal sample_description_index) :
- m_FirstChunk(first_chunk),
- m_FirstSample(first_sample),
- m_ChunkCount(chunk_count),
- m_SamplesPerChunk(samples_per_chunk),
- m_SampleDescriptionIndex(sample_description_index) {}
- AP4_Ordinal m_FirstChunk;
- AP4_Ordinal m_FirstSample; // computed (not in file)
- AP4_Cardinal m_ChunkCount; // computed (not in file)
- AP4_Cardinal m_SamplesPerChunk;
- AP4_Ordinal m_SampleDescriptionIndex;
-};
-
-/*----------------------------------------------------------------------
-| AP4_StscAtom
-+---------------------------------------------------------------------*/
-class AP4_StscAtom : public AP4_Atom
-{
- public:
- // methods
- AP4_StscAtom();
- AP4_StscAtom(AP4_Size size, AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result GetChunkForSample(AP4_Ordinal sample,
- AP4_Ordinal& chunk,
- AP4_Ordinal& skip,
- AP4_Ordinal& sample_description);
- virtual AP4_Result AddEntry(AP4_Cardinal chunk_count,
- AP4_Cardinal samples_per_chunk,
- AP4_Ordinal sample_description_index);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
-
- // FIXME
- friend class AP4_AtomSampleTable;
-
- private:
- // data
- AP4_Array<AP4_StscTableEntry> m_Entries;
- AP4_Ordinal m_CachedChunkGroup;
-};
-
-#endif // _AP4_STSC_ATOM_H_
+/***************************************************************** +| +| AP4 - stsc 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_STSC_ATOM_H_ +#define _AP4_STSC_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Atom.h" +#include "Ap4Array.h" + +/*---------------------------------------------------------------------- +| AP4_StscTableEntry ++---------------------------------------------------------------------*/ +class AP4_StscTableEntry { + public: + AP4_StscTableEntry() : + m_FirstChunk(0), + m_FirstSample(0), + m_ChunkCount(0), + m_SamplesPerChunk(0), + m_SampleDescriptionIndex(0) {} + AP4_StscTableEntry(AP4_Ordinal first_chunk, + AP4_Ordinal first_sample, + AP4_Cardinal samples_per_chunk, + AP4_Ordinal sample_description_index) : + m_FirstChunk(first_chunk), + m_FirstSample(first_sample), + m_ChunkCount(0), + m_SamplesPerChunk(samples_per_chunk), + m_SampleDescriptionIndex(sample_description_index) {} + AP4_StscTableEntry(AP4_Ordinal first_chunk, + AP4_Ordinal first_sample, + AP4_Cardinal chunk_count, + AP4_Cardinal samples_per_chunk, + AP4_Ordinal sample_description_index) : + m_FirstChunk(first_chunk), + m_FirstSample(first_sample), + m_ChunkCount(chunk_count), + m_SamplesPerChunk(samples_per_chunk), + m_SampleDescriptionIndex(sample_description_index) {} + AP4_Ordinal m_FirstChunk; + AP4_Ordinal m_FirstSample; // computed (not in file) + AP4_Cardinal m_ChunkCount; // computed (not in file) + AP4_Cardinal m_SamplesPerChunk; + AP4_Ordinal m_SampleDescriptionIndex; +}; + +/*---------------------------------------------------------------------- +| AP4_StscAtom ++---------------------------------------------------------------------*/ +class AP4_StscAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_StscAtom, AP4_Atom) + + // class methods + static AP4_StscAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_StscAtom(); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result GetChunkForSample(AP4_Ordinal sample, + AP4_Ordinal& chunk, + AP4_Ordinal& skip, + AP4_Ordinal& sample_description_index); + virtual AP4_Result AddEntry(AP4_Cardinal chunk_count, + AP4_Cardinal samples_per_chunk, + AP4_Ordinal sample_description_index); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // methods + AP4_StscAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_Array<AP4_StscTableEntry> m_Entries; + AP4_Ordinal m_CachedChunkGroup; +}; + +#endif // _AP4_STSC_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StsdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StsdAtom.cpp index 7c818538c..4f1b0ece7 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StsdAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StsdAtom.cpp @@ -1,196 +1,219 @@ -/*****************************************************************
-|
-| AP4 - stsd Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4StsdAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-#include "Ap4SampleEntry.h"
-#include "Ap4SampleTable.h"
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom::AP4_StsdAtom
-+---------------------------------------------------------------------*/
-AP4_StsdAtom::AP4_StsdAtom(AP4_SampleTable* sample_table) :
- AP4_ContainerAtom(AP4_ATOM_TYPE_STSD, 4+AP4_FULL_ATOM_HEADER_SIZE, true)
-{
- AP4_Cardinal sample_description_count = sample_table->GetSampleDescriptionCount();
- m_SampleDescriptions.EnsureCapacity(sample_description_count);
- for (AP4_Ordinal i=0; i<sample_description_count; i++) {
- // clear the cache entry
- m_SampleDescriptions.Append(NULL);
-
- // create an entry for the description
- AP4_SampleDescription* sample_description = sample_table->GetSampleDescription(i);
- AP4_Atom* entry = sample_description->ToAtom();
- m_Children.Add(entry);
-
- // update the size
- m_Size += entry->GetSize();
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom::AP4_StsdAtom
-+---------------------------------------------------------------------*/
-AP4_StsdAtom::AP4_StsdAtom(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_ContainerAtom(AP4_ATOM_TYPE_STSD, size, true, stream)
-{
- // read the number of entries
- AP4_UI32 entry_count;
- stream.ReadUI32(entry_count);
-
- // read all entries
- AP4_Size bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-4;
-
- m_Data.SetDataSize(bytes_available);
- stream.Read(m_Data.UseData(), m_Data.GetDataSize());
-
- AP4_ByteStream* s = DNew AP4_MemoryByteStream(m_Data.UseData(), m_Data.GetDataSize());
- for (unsigned int i=0; i<entry_count; i++) {
- AP4_Atom* atom;
- if (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(*s,
- bytes_available,
- atom,
- this))) {
- atom->SetParent(this);
- m_Children.Add(atom);
- }
- }
- s->Release();
-
- // initialize the sample description cache
- m_SampleDescriptions.EnsureCapacity(m_Children.ItemCount());
- for (AP4_Ordinal i=0; i<m_Children.ItemCount(); i++) {
- m_SampleDescriptions.Append(NULL);
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom::~AP4_StsdAtom
-+---------------------------------------------------------------------*/
-AP4_StsdAtom::~AP4_StsdAtom()
-{
- for (AP4_Ordinal i=0; i<m_SampleDescriptions.ItemCount(); i++) {
- delete m_SampleDescriptions[i];
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StsdAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // entry count
- result = stream.WriteUI32(m_Children.ItemCount());
- if (AP4_FAILED(result)) return result;
-
- // entries
- return m_Children.Apply(AP4_AtomListWriter(stream));
-}
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom::OnChildChanged
-+---------------------------------------------------------------------*/
-void
-AP4_StsdAtom::OnChildChanged(AP4_Atom*)
-{
- // remcompute our size
- m_Size = GetHeaderSize()+4;
- m_Children.Apply(AP4_AtomSizeAdder(m_Size));
-
- // update our parent
- if (m_Parent) m_Parent->OnChildChanged(this);
-}
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom::GetSampleDescription
-+---------------------------------------------------------------------*/
-AP4_SampleDescription*
-AP4_StsdAtom::GetSampleDescription(AP4_Ordinal index)
-{
- // check index
- if (index >= m_Children.ItemCount()) return NULL;
-
- // return the description if we already have it in the internal table
- if (m_SampleDescriptions[index]) return m_SampleDescriptions[index];
-
- // create and cache a sample description for this entry
- AP4_Atom* entry;
- m_Children.Get(index, entry);
- AP4_SampleEntry* sample_entry = dynamic_cast<AP4_SampleEntry*>(entry);
- if (sample_entry == NULL) return NULL;
- m_SampleDescriptions[index] = sample_entry->ToSampleDescription();
- return m_SampleDescriptions[index];
-}
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom::GetSampleEntry
-+---------------------------------------------------------------------*/
-AP4_SampleEntry*
-AP4_StsdAtom::GetSampleEntry(AP4_Ordinal index)
-{
- // check index
- if (index >= m_Children.ItemCount()) return NULL;
-
- // return the sample entry
- AP4_Atom* entry;
- m_Children.Get(index, entry);
- return dynamic_cast<AP4_SampleEntry*>(entry);
-}
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom::GetSampleDescriptionCount
-+---------------------------------------------------------------------*/
-AP4_Cardinal
-AP4_StsdAtom::GetSampleDescriptionCount()
-{
- return m_Children.ItemCount();
-}
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StsdAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("entry-count", m_Children.ItemCount());
-
- // inspect children
- m_Children.Apply(AP4_AtomListInspector(inspector));
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - stsd 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 "Ap4StsdAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" +#include "Ap4SampleEntry.h" +#include "Ap4SampleTable.h" +#include "Ap4SampleDescription.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_StsdAtom) + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::Create ++---------------------------------------------------------------------*/ +AP4_StsdAtom* +AP4_StsdAtom::Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) +{ + 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_StsdAtom(size, version, flags, stream, atom_factory); +} + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::AP4_StsdAtom ++---------------------------------------------------------------------*/ +AP4_StsdAtom::AP4_StsdAtom(AP4_SampleTable* sample_table) : + AP4_ContainerAtom(AP4_ATOM_TYPE_STSD, (AP4_UI32)0, (AP4_UI32)0) +{ + m_Size32 += 4; + AP4_Cardinal sample_description_count = sample_table->GetSampleDescriptionCount(); + m_SampleDescriptions.EnsureCapacity(sample_description_count); + for (AP4_Ordinal i=0; i<sample_description_count; i++) { + // clear the cache entry + m_SampleDescriptions.Append(NULL); + + // create an entry for the description + AP4_SampleDescription* sample_description = sample_table->GetSampleDescription(i); + AP4_Atom* entry = sample_description->ToAtom(); + m_Children.Add(entry); + + // update the size + m_Size32 += (AP4_UI32)entry->GetSize(); + } +} + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::AP4_StsdAtom ++---------------------------------------------------------------------*/ +AP4_StsdAtom::AP4_StsdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_ContainerAtom(AP4_ATOM_TYPE_STSD, size, false, version, flags) +{ + // read the number of entries + AP4_UI32 entry_count; + stream.ReadUI32(entry_count); + + // save and switch the factory's context + atom_factory.PushContext(m_Type); + + // read all entries + AP4_LargeSize bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-4; + for (unsigned int i=0; i<entry_count; i++) { + AP4_Atom* atom; + if (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, + bytes_available, + atom))) { + atom->SetParent(this); + m_Children.Add(atom); + } + } + + // restore the saved context + atom_factory.PopContext(); + + // initialize the sample description cache + m_SampleDescriptions.EnsureCapacity(m_Children.ItemCount()); + for (AP4_Ordinal i=0; i<m_Children.ItemCount(); i++) { + m_SampleDescriptions.Append(NULL); + } +} + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::~AP4_StsdAtom ++---------------------------------------------------------------------*/ +AP4_StsdAtom::~AP4_StsdAtom() +{ + for (AP4_Ordinal i=0; i<m_SampleDescriptions.ItemCount(); i++) { + delete m_SampleDescriptions[i]; + } +} + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StsdAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // entry count + result = stream.WriteUI32(m_Children.ItemCount()); + if (AP4_FAILED(result)) return result; + + // entries + return m_Children.Apply(AP4_AtomListWriter(stream)); +} + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::OnChildChanged ++---------------------------------------------------------------------*/ +void +AP4_StsdAtom::OnChildChanged(AP4_Atom*) +{ + // remcompute our size + AP4_UI64 size = GetHeaderSize()+4; + m_Children.Apply(AP4_AtomSizeAdder(size)); + m_Size32 = (AP4_UI32)size; + + // update our parent + if (m_Parent) m_Parent->OnChildChanged(this); +} + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::GetSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_StsdAtom::GetSampleDescription(AP4_Ordinal index) +{ + // check index + if (index >= m_Children.ItemCount()) return NULL; + + // return the description if we already have it in the internal table + if (m_SampleDescriptions[index]) return m_SampleDescriptions[index]; + + // create and cache a sample description for this entry + AP4_Atom* entry; + m_Children.Get(index, entry); + AP4_SampleEntry* sample_entry = AP4_DYNAMIC_CAST(AP4_SampleEntry, entry); + if (sample_entry == NULL) return NULL; + m_SampleDescriptions[index] = sample_entry->ToSampleDescription(); + return m_SampleDescriptions[index]; +} + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::GetSampleEntry ++---------------------------------------------------------------------*/ +AP4_SampleEntry* +AP4_StsdAtom::GetSampleEntry(AP4_Ordinal index) +{ + // check index + if (index >= m_Children.ItemCount()) return NULL; + + // return the sample entry + AP4_Atom* entry; + m_Children.Get(index, entry); + return AP4_DYNAMIC_CAST(AP4_SampleEntry, entry); +} + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::GetSampleDescriptionCount ++---------------------------------------------------------------------*/ +AP4_Cardinal +AP4_StsdAtom::GetSampleDescriptionCount() +{ + return m_Children.ItemCount(); +} + +/*---------------------------------------------------------------------- +| AP4_StsdAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StsdAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("entry-count", m_Children.ItemCount()); + + // inspect children + m_Children.Apply(AP4_AtomListInspector(inspector)); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StsdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StsdAtom.h index 83f1b036d..8a5013a72 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StsdAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StsdAtom.h @@ -1,80 +1,84 @@ -/*****************************************************************
-|
-| AP4 - stsd Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_STSD_ATOM_H_
-#define _AP4_STSD_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4Types.h"
-#include "Ap4Array.h"
-#include "Ap4ByteStream.h"
-#include "Ap4List.h"
-#include "Ap4Atom.h"
-#include "Ap4SampleDescription.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4ContainerAtom.h"
-
-/*----------------------------------------------------------------------
-| class references
-+---------------------------------------------------------------------*/
-class AP4_SampleTable;
-
-/*----------------------------------------------------------------------
-| AP4_StsdAtom
-+---------------------------------------------------------------------*/
-class AP4_StsdAtom : public AP4_ContainerAtom
-{
- public:
- // methods
- AP4_StsdAtom(AP4_SampleTable* sample_table);
- AP4_StsdAtom(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
- ~AP4_StsdAtom();
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
- virtual AP4_Cardinal GetSampleDescriptionCount();
- virtual AP4_SampleDescription* GetSampleDescription(AP4_Ordinal index);
- virtual AP4_SampleEntry* GetSampleEntry(AP4_Ordinal index);
-
- // AP4_AtomParent methods
- void OnChildChanged(AP4_Atom* child);
-
- const AP4_DataBuffer& GetDataBuffer() { return m_Data; }
-
-private:
- // members
- AP4_DataBuffer m_Data;
- AP4_Array<AP4_SampleDescription*> m_SampleDescriptions;
-};
-
-#endif // _AP4_STSD_ATOM_H_
-
+/***************************************************************** +| +| AP4 - stsd 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_STSD_ATOM_H_ +#define _AP4_STSD_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Array.h" +#include "Ap4ContainerAtom.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_SampleTable; +class AP4_SampleDescription; +class AP4_SampleEntry; + +/*---------------------------------------------------------------------- +| AP4_StsdAtom ++---------------------------------------------------------------------*/ +class AP4_StsdAtom : public AP4_ContainerAtom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_StsdAtom, AP4_ContainerAtom) + + // class methods + static AP4_StsdAtom* Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // methods + AP4_StsdAtom(AP4_SampleTable* sample_table); + ~AP4_StsdAtom(); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_Cardinal GetSampleDescriptionCount(); + virtual AP4_SampleDescription* GetSampleDescription(AP4_Ordinal index); + virtual AP4_SampleEntry* GetSampleEntry(AP4_Ordinal index); + + // AP4_AtomParent methods + void OnChildChanged(AP4_Atom* child); + +private: + // methods + AP4_StsdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // members + AP4_Array<AP4_SampleDescription*> m_SampleDescriptions; +}; + +#endif // _AP4_STSD_ATOM_H_ + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StssAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StssAtom.cpp index e6eaaf284..23d06f82d 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StssAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StssAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - stss Atoms | -| Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,18 +27,47 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4StssAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_StssAtom::AP4_StssAtom +| dynamic cast support +---------------------------------------------------------------------*/ -AP4_StssAtom::AP4_StssAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_STSS, size, true, stream) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_StssAtom) + +/*---------------------------------------------------------------------- +| AP4_StssAtom::Create ++---------------------------------------------------------------------*/ +AP4_StssAtom* +AP4_StssAtom::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_StssAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_StssAtom::AP4_StssAtom ++---------------------------------------------------------------------*/ +AP4_StssAtom::AP4_StssAtom() : + AP4_Atom(AP4_ATOM_TYPE_STSS, AP4_FULL_ATOM_HEADER_SIZE+4, 0, 0) +{ +} + +/*---------------------------------------------------------------------- +| AP4_StssAtom::AP4_StssAtom ++---------------------------------------------------------------------*/ +AP4_StssAtom::AP4_StssAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_STSS, size, version, flags), + m_LookupCache(0) { AP4_UI32 entry_count; stream.ReadUI32(entry_count); @@ -51,7 +80,7 @@ AP4_StssAtom::AP4_StssAtom(AP4_Size size, AP4_ByteStream& stream) : } /*---------------------------------------------------------------------- -| AP4_StssAtom::WriteFields +| AP4_StssAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_StssAtom::WriteFields(AP4_ByteStream& stream) @@ -73,26 +102,48 @@ AP4_StssAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_StssAtom::IsSampleSync +| AP4_StssAtom::AddEntry ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StssAtom::AddEntry(AP4_UI32 sample) +{ + m_Entries.Append(sample); + m_Size32 += 4; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_StssAtom::IsSampleSync +---------------------------------------------------------------------*/ bool AP4_StssAtom::IsSampleSync(AP4_Ordinal sample) { unsigned int entry_index = 0; + // check bounds + if (sample == 0 || m_Entries.ItemCount() == 0) return false; + + // see if we can start from the cached index + if (m_Entries[m_LookupCache] <= sample) { + entry_index = m_LookupCache; + } + + // do a linear search while (entry_index < m_Entries.ItemCount() && - m_Entries[entry_index] >= sample) { + m_Entries[entry_index] <= sample) { if (m_Entries[entry_index] == sample) { + m_LookupCache = entry_index; return true; } - entry_index++; + entry_index++; } return false; } /*---------------------------------------------------------------------- -| AP4_StssAtom::InspectFields +| AP4_StssAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_StssAtom::InspectFields(AP4_AtomInspector& inspector) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StssAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StssAtom.h index ecd763097..0384cb6a3 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StssAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StssAtom.h @@ -1,56 +1,72 @@ -/*****************************************************************
-|
-| AP4 - stss Atoms
-|
-| Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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_STSS_ATOM_H_
-#define _AP4_STSS_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4Array.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| AP4_StssAtom
-+---------------------------------------------------------------------*/
-class AP4_StssAtom : public AP4_Atom
-{
- public:
- // methods
- AP4_StssAtom(AP4_Size size, AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual bool IsSampleSync(AP4_Ordinal sample);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
-
- AP4_Array<AP4_UI32> m_Entries; // FIXME
- private:
-};
-
-#endif // _AP4_STSS_ATOM_H_
+/***************************************************************** +| +| AP4 - stss 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_STSS_ATOM_H_ +#define _AP4_STSS_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Array.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_StssAtom ++---------------------------------------------------------------------*/ +class AP4_StssAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_StssAtom, AP4_Atom) + + // class methods + static AP4_StssAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // constructor + AP4_StssAtom(); + + // methods + // methods + const AP4_Array<AP4_UI32>& GetEntries() { return m_Entries; } + AP4_Result AddEntry(AP4_UI32 sample); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual bool IsSampleSync(AP4_Ordinal sample); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // methods + AP4_StssAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_Array<AP4_UI32> m_Entries; + AP4_Ordinal m_LookupCache; +}; + +#endif // _AP4_STSS_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StszAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StszAtom.cpp index 1e84a475d..97dfc9f91 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StszAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StszAtom.cpp @@ -1,194 +1,211 @@ -/*****************************************************************
-|
-| AP4 - stsz Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4StszAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom::AP4_StszAtom
-+---------------------------------------------------------------------*/
-AP4_StszAtom::AP4_StszAtom() :
- AP4_Atom(AP4_ATOM_TYPE_STSZ, AP4_FULL_ATOM_HEADER_SIZE+8, true),
- m_SampleSize(0),
- m_SampleCount(0)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom::AP4_StszAtom
-+---------------------------------------------------------------------*/
-AP4_StszAtom::AP4_StszAtom(AP4_Size size, AP4_ByteStream& stream) :
- AP4_Atom(AP4_ATOM_TYPE_STSZ, size, true, stream)
-{
- stream.ReadUI32(m_SampleSize);
- stream.ReadUI32(m_SampleCount);
- unsigned long sample_count = m_SampleCount;
- if (m_SampleSize == 0) { // means that the samples have different sizes
- while (sample_count--) {
- AP4_UI32 entry_size;
- if (stream.ReadUI32(entry_size) == AP4_SUCCESS) {
- m_Entries.Append(entry_size);
- }
- }
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StszAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // sample size
- result = stream.WriteUI32(m_SampleSize);
- if (AP4_FAILED(result)) return result;
-
- // sample count
- result = stream.WriteUI32(m_SampleCount);
- if (AP4_FAILED(result)) return result;
-
- // entries if needed (the samples have different sizes)
- if (m_SampleSize == 0) {
- for (AP4_UI32 i=0; i<m_SampleCount; i++) {
- result = stream.WriteUI32(m_Entries[i]);
- if (AP4_FAILED(result)) return result;
- }
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom::GetSampleCount
-+---------------------------------------------------------------------*/
-AP4_UI32
-AP4_StszAtom::GetSampleCount()
-{
- return m_SampleCount;
-}
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom::GetSampleSize
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StszAtom::GetSampleSize(AP4_Ordinal sample_start,
- AP4_Ordinal sample_end,
- AP4_Size& sample_size)
-{
- sample_size = 0;
-
- if(sample_start > m_SampleCount || sample_end > m_SampleCount)
- {
- return AP4_ERROR_OUT_OF_RANGE;
- }
-
- if(m_SampleSize != 0)
- {
- sample_size = m_SampleSize * (sample_end - sample_start);
- }
- else
- {
- // compute the additional offset inside the chunk
- for (unsigned int i = sample_start; i < sample_end; i++) {
- AP4_Size size;
- AP4_Result result = GetSampleSize(i, size);
- if (AP4_FAILED(result)) return result;
- sample_size += size;
- }
- }
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom::GetSampleSize
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StszAtom::GetSampleSize(AP4_Ordinal sample, AP4_Size& sample_size)
-{
- // check the sample index
- if (sample > m_SampleCount) {
- sample_size = 0;
- return AP4_ERROR_OUT_OF_RANGE;
- } else {
- // find the size
- if (m_SampleSize != 0) { // constant size
- sample_size = m_SampleSize;
- } else {
- sample_size = m_Entries[sample - 1];
- }
- return AP4_SUCCESS;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom::SetSampleSize
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StszAtom::SetSampleSize(AP4_Ordinal sample, AP4_Size sample_size)
-{
- // check the sample index
- if (sample > m_SampleCount) {
- return AP4_ERROR_OUT_OF_RANGE;
- } else {
- m_Entries[sample - 1] = sample_size;
- return AP4_SUCCESS;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom::AddEntry
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StszAtom::AddEntry(AP4_UI32 size)
-{
- m_Entries.Append(size);
- m_SampleCount++;
- m_Size += 4;
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_StszAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("sample_size", m_SampleSize);
- inspector.AddField("sample_count", m_Entries.ItemCount());
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - stsz 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 "Ap4StszAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_StszAtom) + +/*---------------------------------------------------------------------- +| AP4_StszAtom::Create ++---------------------------------------------------------------------*/ +AP4_StszAtom* +AP4_StszAtom::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_StszAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_StszAtom::AP4_StszAtom ++---------------------------------------------------------------------*/ +AP4_StszAtom::AP4_StszAtom() : + AP4_Atom(AP4_ATOM_TYPE_STSZ, AP4_FULL_ATOM_HEADER_SIZE+8, 0, 0), + m_SampleSize(0), + m_SampleCount(0) +{ +} + +/*---------------------------------------------------------------------- +| AP4_StszAtom::AP4_StszAtom ++---------------------------------------------------------------------*/ +AP4_StszAtom::AP4_StszAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_STSZ, size, version, flags) +{ + stream.ReadUI32(m_SampleSize); + stream.ReadUI32(m_SampleCount); + if (m_SampleSize == 0) { // means that the samples have different sizes + unsigned long sample_count = m_SampleCount; + m_Entries.SetItemCount(sample_count); + unsigned char* buffer = new unsigned char[sample_count*4]; + AP4_Result result = stream.Read(buffer, sample_count*4); + if (AP4_FAILED(result)) { + delete[] buffer; + return; + } + for (unsigned int i=0; i<sample_count; i++) { + m_Entries[i] = AP4_BytesToUInt32BE(&buffer[i*4]); + } + delete[] buffer; + } +} + +/*---------------------------------------------------------------------- +| AP4_StszAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StszAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // sample size + result = stream.WriteUI32(m_SampleSize); + if (AP4_FAILED(result)) return result; + + // sample count + result = stream.WriteUI32(m_SampleCount); + if (AP4_FAILED(result)) return result; + + // entries if needed (the samples have different sizes) + if (m_SampleSize == 0) { + for (AP4_UI32 i=0; i<m_SampleCount; i++) { + result = stream.WriteUI32(m_Entries[i]); + if (AP4_FAILED(result)) return result; + } + } + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_StszAtom::GetSampleCount ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_StszAtom::GetSampleCount() +{ + return m_SampleCount; +} + +/*---------------------------------------------------------------------- +| AP4_StszAtom::GetSampleSize ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StszAtom::GetSampleSize(AP4_Ordinal sample, AP4_Size& sample_size) +{ + // check the sample index + if (sample > m_SampleCount || sample == 0) { + sample_size = 0; + return AP4_ERROR_OUT_OF_RANGE; + } else { + // find the size + if (m_SampleSize != 0) { // constant size + sample_size = m_SampleSize; + } else { + sample_size = m_Entries[sample - 1]; + } + return AP4_SUCCESS; + } +} + +/*---------------------------------------------------------------------- +| AP4_StszAtom::SetSampleSize ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StszAtom::SetSampleSize(AP4_Ordinal sample, AP4_Size sample_size) +{ + // check the sample index + if (sample > m_SampleCount || sample == 0) { + return AP4_ERROR_OUT_OF_RANGE; + } else { + if (m_Entries.ItemCount() == 0) { + // all samples must have the same size + if (sample_size != m_SampleSize) { + // not the same + if (sample == 1) { + // if this is the first sample, update the global size + m_SampleSize = sample_size; + return AP4_SUCCESS; + } else { + // can't have different sizes + return AP4_ERROR_INVALID_PARAMETERS; + } + } + } else { + // each sample has a different size + m_Entries[sample - 1] = sample_size; + } + + return AP4_SUCCESS; + } +} + +/*---------------------------------------------------------------------- +| AP4_StszAtom::AddEntry ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StszAtom::AddEntry(AP4_UI32 size) +{ + m_Entries.Append(size); + m_SampleCount++; + m_Size32 += 4; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_StszAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StszAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("sample_size", m_SampleSize); + inspector.AddField("sample_count", m_Entries.ItemCount()); + + if (inspector.GetVerbosity() >= 2) { + char header[32]; + for (AP4_Ordinal i=0; i<m_Entries.ItemCount(); i++) { + AP4_FormatString(header, sizeof(header), "entry %8d", i); + inspector.AddField(header, m_Entries[i]); + } + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StszAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StszAtom.h index 91fd38aad..25cfa42cd 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StszAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4StszAtom.h @@ -1,70 +1,83 @@ -/*****************************************************************
-|
-| AP4 - stsz Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_STSZ_ATOM_H_
-#define _AP4_STSZ_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4Array.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| AP4_StszAtom
-+---------------------------------------------------------------------*/
-class AP4_StszAtom : public AP4_Atom
-{
- public:
- // methods
- AP4_StszAtom();
- AP4_StszAtom(AP4_Size size, AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
- virtual AP4_UI32 GetSampleCount();
- virtual AP4_Result GetSampleSize(AP4_Ordinal sample_start,
- AP4_Ordinal sample_end,
- AP4_Size& sample_size);
- virtual AP4_Result GetSampleSize(AP4_Ordinal sample,
- AP4_Size& sample_size);
- virtual AP4_Result SetSampleSize(AP4_Ordinal sample,
- AP4_Size sample_size);
- virtual AP4_Result AddEntry(AP4_UI32 size);
-
- // FIXME
- friend class AP4_AtomSampleTable;
-
- private:
- AP4_UI32 m_SampleSize;
- AP4_UI32 m_SampleCount;
- AP4_Array<AP4_UI32> m_Entries;
-};
-
-#endif // _AP4_STSZ_ATOM_H_
+/***************************************************************** +| +| AP4 - stsz 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_STSZ_ATOM_H_ +#define _AP4_STSZ_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Array.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_StszAtom ++---------------------------------------------------------------------*/ +class AP4_StszAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_StszAtom, AP4_Atom) + + // class methods + static AP4_StszAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_StszAtom(); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + virtual AP4_UI32 GetSampleCount(); + virtual AP4_Result GetSampleSize(AP4_Ordinal sample, + AP4_Size& sample_size); + /** + * Set the sample size. + * @param sample 1-based index of a sample. + * @param sample_size Size of the sample. + * If this table represents a global-size table (one where there are + * no individual entries for each sample, but all sample have the same + * size = m_SampleSize), then calling this method with sample=1 will update + * the global size, and calling with sample>1 will check that + * the value of sample_size is the same as the global size m_SampleSize. + */ + virtual AP4_Result SetSampleSize(AP4_Ordinal sample, + AP4_Size sample_size); + virtual AP4_Result AddEntry(AP4_UI32 size); + +private: + // methods + AP4_StszAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI32 m_SampleSize; + AP4_UI32 m_SampleCount; + AP4_Array<AP4_UI32> m_Entries; +}; + +#endif // _AP4_STSZ_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SttsAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SttsAtom.cpp index 666207113..15a8d8418 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SttsAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SttsAtom.cpp @@ -1,169 +1,236 @@ -/*****************************************************************
-|
-| AP4 - stts Atoms
-|
-| Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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 "Ap4.h"
-#include "Ap4SttsAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_SttsAtom::AP4_SttsAtom
-+---------------------------------------------------------------------*/
-AP4_SttsAtom::AP4_SttsAtom() :
- AP4_Atom(AP4_ATOM_TYPE_STTS, AP4_FULL_ATOM_HEADER_SIZE+4, true)
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_SttsAtom::AP4_SttsAtom
-+---------------------------------------------------------------------*/
-AP4_SttsAtom::AP4_SttsAtom(AP4_Size size, AP4_ByteStream& stream) :
- AP4_Atom(AP4_ATOM_TYPE_STTS, size, true, stream)
-{
- AP4_UI32 entry_count;
- stream.ReadUI32(entry_count);
- while (entry_count--) {
- AP4_UI32 sample_count;
- AP4_UI32 sample_duration;
- if (stream.ReadUI32(sample_count) == AP4_SUCCESS &&
- stream.ReadUI32(sample_duration) == AP4_SUCCESS) {
- m_Entries.Append(AP4_SttsTableEntry(sample_count,
- sample_duration));
- }
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_SttsAtom::GetDts
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SttsAtom::GetDts(AP4_Ordinal sample, AP4_TimeStamp& dts, AP4_Duration& duration)
-{
- AP4_Ordinal sample_count_in_entry = sample;
- dts = 0;
-
- for (AP4_UI32 i = 0; i < m_Entries.ItemCount(); i++) {
- AP4_SttsTableEntry& entry = m_Entries[i];
-
- // check if we have the correct entry
- if (sample_count_in_entry <= entry.m_SampleCount) {
- dts += (sample_count_in_entry - 1) * entry.m_SampleDuration;
- duration = entry.m_SampleDuration;
- return AP4_SUCCESS;
- } else {
- dts += entry.m_SampleCount * entry.m_SampleDuration;
- sample_count_in_entry -= entry.m_SampleCount;
- }
- }
-
- // sample is greater than the number of samples
- return AP4_FAILURE;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SttsAtom::AddEntry
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SttsAtom::AddEntry(AP4_UI32 sample_count, AP4_UI32 sample_duration)
-{
- m_Entries.Append(AP4_SttsTableEntry(sample_count, sample_duration));
- m_Size += 8;
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SttsAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SttsAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // write the entry count
- AP4_Cardinal entry_count = m_Entries.ItemCount();
- result = stream.WriteUI32(entry_count);
- if (AP4_FAILED(result)) return result;
-
- // write the entries
- for (AP4_Ordinal i=0; i<entry_count; i++) {
- // sample count
- result = stream.WriteUI32(m_Entries[i].m_SampleCount);
- if (AP4_FAILED(result)) return result;
-
- // time offset
- result = stream.WriteUI32(m_Entries[i].m_SampleDuration);
- if (AP4_FAILED(result)) return result;
- }
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SttsAtom::GetSampleIndexForTimeStamp
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SttsAtom::GetSampleIndexForTimeStamp(AP4_TimeStamp ts, AP4_Ordinal& sample)
-{
- // init
- AP4_Cardinal entry_count = m_Entries.ItemCount();
- AP4_Duration accumulated = 0;
- sample = 0;
-
- for (AP4_Ordinal i=0; i<entry_count; i++) {
- AP4_Duration next_accumulated = accumulated
- + m_Entries[i].m_SampleCount * m_Entries[i].m_SampleDuration;
-
- // check if the ts is in the range of this entry
- if (ts < next_accumulated) {
- sample += (AP4_Ordinal) ((ts - accumulated) / m_Entries[i].m_SampleDuration);
- return AP4_SUCCESS;
- }
-
- // update accumulated and sample
- accumulated = next_accumulated;
- sample += m_Entries[i].m_SampleCount;
- }
-
- // ts not in range of the table
- return AP4_FAILURE;
-}
-
-/*----------------------------------------------------------------------
-| AP4_SttsAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SttsAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("entry_count", m_Entries.ItemCount());
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - stts 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 "Ap4SttsAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_SttsAtom) + +/*---------------------------------------------------------------------- +| AP4_SttsAtom::Create ++---------------------------------------------------------------------*/ +AP4_SttsAtom* +AP4_SttsAtom::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_SttsAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_SttsAtom::AP4_SttsAtom ++---------------------------------------------------------------------*/ +AP4_SttsAtom::AP4_SttsAtom() : + AP4_Atom(AP4_ATOM_TYPE_STTS, AP4_FULL_ATOM_HEADER_SIZE+4, 0, 0) +{ + m_LookupCache.entry_index = 0; + m_LookupCache.sample = 0; + m_LookupCache.dts = 0; +} + +/*---------------------------------------------------------------------- +| AP4_SttsAtom::AP4_SttsAtom ++---------------------------------------------------------------------*/ +AP4_SttsAtom::AP4_SttsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_STTS, size, version, flags) +{ + m_LookupCache.entry_index = 0; + m_LookupCache.sample = 0; + m_LookupCache.dts = 0; + + AP4_UI32 entry_count; + stream.ReadUI32(entry_count); + while (entry_count--) { + AP4_UI32 sample_count; + AP4_UI32 sample_duration; + if (stream.ReadUI32(sample_count) == AP4_SUCCESS && + stream.ReadUI32(sample_duration) == AP4_SUCCESS) { + m_Entries.Append(AP4_SttsTableEntry(sample_count, + sample_duration)); + } + } +} + +/*---------------------------------------------------------------------- +| AP4_SttsAtom::GetDts ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SttsAtom::GetDts(AP4_Ordinal sample, AP4_UI64& dts, AP4_UI32* duration) +{ + // default value + dts = 0; + if (duration) *duration = 0; + + // sample indexes start at 1 + if (sample == 0) return AP4_ERROR_OUT_OF_RANGE; + + // check the lookup cache + AP4_Ordinal lookup_start = 0; + AP4_Ordinal sample_start = 0; + AP4_UI64 dts_start = 0; + if (sample >= m_LookupCache.sample) { + // start from the cached entry + lookup_start = m_LookupCache.entry_index; + sample_start = m_LookupCache.sample; + dts_start = m_LookupCache.dts; + } + + // look from the last known point + for (AP4_Ordinal i = lookup_start; i < m_Entries.ItemCount(); i++) { + AP4_SttsTableEntry& entry = m_Entries[i]; + + // check if we have reached the sample + if (sample <= sample_start+entry.m_SampleCount) { + // we are within the sample range for the current entry + dts = dts_start + (AP4_UI64)(sample-1 - sample_start) * (AP4_UI64)entry.m_SampleDuration; + if (duration) *duration = entry.m_SampleDuration; + + // update the lookup cache + m_LookupCache.entry_index = i; + m_LookupCache.sample = sample_start; + m_LookupCache.dts = dts_start; + + return AP4_SUCCESS; + } + + // update the sample and dts bases + sample_start += entry.m_SampleCount; + dts_start += entry.m_SampleCount*entry.m_SampleDuration; + } + + // sample is greater than the number of samples + return AP4_ERROR_OUT_OF_RANGE; +} + +/*---------------------------------------------------------------------- +| AP4_SttsAtom::AddEntry ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SttsAtom::AddEntry(AP4_UI32 sample_count, AP4_UI32 sample_duration) +{ + m_Entries.Append(AP4_SttsTableEntry(sample_count, sample_duration)); + m_Size32 += 8; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_SttsAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SttsAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // write the entry count + AP4_Cardinal entry_count = m_Entries.ItemCount(); + result = stream.WriteUI32(entry_count); + if (AP4_FAILED(result)) return result; + + // write the entries + for (AP4_Ordinal i=0; i<entry_count; i++) { + // sample count + result = stream.WriteUI32(m_Entries[i].m_SampleCount); + if (AP4_FAILED(result)) return result; + + // time offset + result = stream.WriteUI32(m_Entries[i].m_SampleDuration); + if (AP4_FAILED(result)) return result; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_SttsAtom::GetSampleIndexForTimeStamp ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SttsAtom::GetSampleIndexForTimeStamp(AP4_UI64 ts, + AP4_Ordinal& sample_index) +{ + // init + AP4_Cardinal entry_count = m_Entries.ItemCount(); + AP4_UI64 accumulated = 0; + sample_index = 0; + + for (AP4_Ordinal i=0; i<entry_count; i++) { + AP4_UI64 next_accumulated = + accumulated + + (AP4_UI64)m_Entries[i].m_SampleCount * + (AP4_UI64)m_Entries[i].m_SampleDuration; + + // check if the ts is in the range of this entry + if (ts < next_accumulated) { + sample_index += (AP4_UI32)((ts - accumulated) / m_Entries[i].m_SampleDuration); + return AP4_SUCCESS; + } + + // update accumulated and sample + accumulated = next_accumulated; + sample_index += m_Entries[i].m_SampleCount; + } + + // ts not in range of the table + return AP4_FAILURE; +} + +/*---------------------------------------------------------------------- +| AP4_SttsAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SttsAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("entry_count", m_Entries.ItemCount()); + + if (inspector.GetVerbosity() >= 1) { + char header[32]; + char value[256]; + for (AP4_Ordinal i=0; i<m_Entries.ItemCount(); i++) { + AP4_FormatString(header, sizeof(header), "entry %8d", i); + AP4_FormatString(value, sizeof(value), + "sample_count=%d, sample_duration=%d", + m_Entries[i].m_SampleCount, + m_Entries[i].m_SampleDuration); + inspector.AddField(header, value); + } + } + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SttsAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SttsAtom.h index 2f56e2b5a..14349d453 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SttsAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SttsAtom.h @@ -1,80 +1,91 @@ -/*****************************************************************
-|
-| AP4 - stts Atoms
-|
-| Copyright 2003 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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_STTS_ATOM_H_
-#define _AP4_STTS_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4Array.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| AP4_SttsTableEntry
-+---------------------------------------------------------------------*/
-class AP4_SttsTableEntry {
- public:
- AP4_SttsTableEntry() :
- m_SampleCount(0),
- m_SampleDuration(0) {}
- AP4_SttsTableEntry(AP4_Cardinal sample_count,
- AP4_Duration sample_duration) :
- m_SampleCount(sample_count),
- m_SampleDuration(sample_duration) {}
-
- AP4_Cardinal m_SampleCount;
- AP4_Duration m_SampleDuration;
-};
-
-/*----------------------------------------------------------------------
-| AP4_SttsAtom
-+---------------------------------------------------------------------*/
-class AP4_SttsAtom : public AP4_Atom
-{
- public:
- // methods
- AP4_SttsAtom();
- AP4_SttsAtom(AP4_Size size, AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result GetDts(AP4_Ordinal sample, AP4_TimeStamp& dts, AP4_Duration& duration);
- virtual AP4_Result AddEntry(AP4_UI32 sample_count, AP4_UI32 sample_duration);
- virtual AP4_Result GetSampleIndexForTimeStamp(AP4_TimeStamp ts,
- AP4_Ordinal& sample);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
-
- // FIXME
- friend class AP4_AtomSampleTable;
-
- private:
- AP4_Array<AP4_SttsTableEntry> m_Entries;
-};
-
-#endif // _AP4_STTS_ATOM_H_
+/***************************************************************** +| +| AP4 - stts 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_STTS_ATOM_H_ +#define _AP4_STTS_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Array.h" +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| AP4_SttsTableEntry ++---------------------------------------------------------------------*/ +class AP4_SttsTableEntry { + public: + AP4_SttsTableEntry() : + m_SampleCount(0), + m_SampleDuration(0) {} + AP4_SttsTableEntry(AP4_UI32 sample_count, + AP4_UI32 sample_duration) : + m_SampleCount(sample_count), + m_SampleDuration(sample_duration) {} + + AP4_UI32 m_SampleCount; + AP4_UI32 m_SampleDuration; +}; + +/*---------------------------------------------------------------------- +| AP4_SttsAtom ++---------------------------------------------------------------------*/ +class AP4_SttsAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_SttsAtom, AP4_Atom) + + // class methods + static AP4_SttsAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_SttsAtom(); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result GetDts(AP4_Ordinal sample, AP4_UI64& dts, AP4_UI32* duration = NULL); + virtual AP4_Result AddEntry(AP4_UI32 sample_count, AP4_UI32 sample_duration); + virtual AP4_Result GetSampleIndexForTimeStamp(AP4_UI64 ts, + AP4_Ordinal& sample_index); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + +private: + // methods + AP4_SttsAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_Array<AP4_SttsTableEntry> m_Entries; + struct { + AP4_Ordinal entry_index; + AP4_Ordinal sample; + AP4_UI64 dts; + } m_LookupCache; +}; + +#endif // _AP4_STTS_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SyntheticSampleTable.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SyntheticSampleTable.cpp index ae06d760a..8a9178a3b 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SyntheticSampleTable.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SyntheticSampleTable.cpp @@ -2,7 +2,7 @@ | | AP4 - Synthetic Sample Table | -| Copyright 2003-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,21 +27,23 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" +#include "Ap4Types.h" #include "Ap4Atom.h" #include "Ap4SyntheticSampleTable.h" +#include "Ap4Sample.h" /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable::AP4_SyntheticSampleTable() +| AP4_SyntheticSampleTable::AP4_SyntheticSampleTable() +---------------------------------------------------------------------*/ -AP4_SyntheticSampleTable::AP4_SyntheticSampleTable() +AP4_SyntheticSampleTable::AP4_SyntheticSampleTable(AP4_Cardinal chunk_size) : + m_ChunkSize(chunk_size?chunk_size:AP4_SYNTHETIC_SAMPLE_TABLE_DEFAULT_CHUNK_SIZE) { } /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable::~AP4_SyntheticSampleTable() +| AP4_SyntheticSampleTable::~AP4_SyntheticSampleTable() +---------------------------------------------------------------------*/ AP4_SyntheticSampleTable::~AP4_SyntheticSampleTable() { @@ -49,21 +51,19 @@ AP4_SyntheticSampleTable::~AP4_SyntheticSampleTable() } /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable::GetSample +| AP4_SyntheticSampleTable::GetSample +---------------------------------------------------------------------*/ AP4_Result -AP4_SyntheticSampleTable::GetSample(AP4_Ordinal index, AP4_Sample& sample) +AP4_SyntheticSampleTable::GetSample(AP4_Ordinal sample_index, AP4_Sample& sample) { - if (index < m_Samples.ItemCount()) { - sample = m_Samples[index]; - return AP4_SUCCESS; - } else { - return AP4_ERROR_OUT_OF_RANGE; - } + if (sample_index >= m_Samples.ItemCount()) return AP4_ERROR_OUT_OF_RANGE; + + sample = m_Samples[sample_index]; + return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable::GetSampleCount +| AP4_SyntheticSampleTable::GetSampleCount +---------------------------------------------------------------------*/ AP4_Cardinal AP4_SyntheticSampleTable::GetSampleCount() @@ -72,7 +72,31 @@ AP4_SyntheticSampleTable::GetSampleCount() } /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable::GetSampleDescriptionCount +| AP4_SyntheticSampleTable::GetSampleChunkPosition ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SyntheticSampleTable::GetSampleChunkPosition( + AP4_Ordinal sample_index, + AP4_Ordinal& chunk_index, + AP4_Ordinal& position_in_chunk) +{ + // default values + chunk_index = 0; + position_in_chunk = 0; + + // check parameters + if (sample_index >= m_Samples.ItemCount()) return AP4_ERROR_OUT_OF_RANGE; + if (m_ChunkSize == 0) return AP4_ERROR_INVALID_STATE; + + // compute in which chunk this sample falls + chunk_index = sample_index/m_ChunkSize; + position_in_chunk = sample_index%m_ChunkSize; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_SyntheticSampleTable::GetSampleDescriptionCount +---------------------------------------------------------------------*/ AP4_Cardinal AP4_SyntheticSampleTable::GetSampleDescriptionCount() @@ -81,50 +105,95 @@ AP4_SyntheticSampleTable::GetSampleDescriptionCount() } /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable::GetSampleDescription +| AP4_SyntheticSampleTable::GetSampleDescription +---------------------------------------------------------------------*/ AP4_SampleDescription* AP4_SyntheticSampleTable::GetSampleDescription(AP4_Ordinal index) { - AP4_SampleDescription* description; - if (AP4_SUCCEEDED(m_SampleDescriptions.Get(index, description))) { - return description; + SampleDescriptionHolder* holder; + if (AP4_SUCCEEDED(m_SampleDescriptions.Get(index, holder))) { + return holder->m_SampleDescription; } else { return NULL; } } /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable::AddSampleDescription +| AP4_SyntheticSampleTable::AddSampleDescription +---------------------------------------------------------------------*/ AP4_Result -AP4_SyntheticSampleTable::AddSampleDescription(AP4_SampleDescription* description) +AP4_SyntheticSampleTable::AddSampleDescription(AP4_SampleDescription* description, + bool transfer_ownership) { - return m_SampleDescriptions.Add(description); + return m_SampleDescriptions.Add(new SampleDescriptionHolder(description, transfer_ownership)); } /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable::AddSample +| AP4_SyntheticSampleTable::AddSample +---------------------------------------------------------------------*/ AP4_Result AP4_SyntheticSampleTable::AddSample(AP4_ByteStream& data_stream, - AP4_Offset offset, + AP4_Position offset, AP4_Size size, + AP4_UI32 duration, AP4_Ordinal description_index, - AP4_TimeStamp cts, - AP4_TimeStamp dts, + AP4_UI64 dts, + AP4_UI32 cts_delta, bool sync) { - AP4_Sample sample(data_stream, offset, size, description_index, dts, cts-dts); + if (m_Samples.ItemCount() > 0) { + AP4_Sample* prev_sample = &m_Samples[m_Samples.ItemCount()-1]; + if (dts == 0) { + if (prev_sample->GetDuration() == 0) { + // can't compute the DTS for this sample + return AP4_ERROR_INVALID_PARAMETERS; + } + dts = prev_sample->GetDts()+prev_sample->GetDuration(); + } else { + if (prev_sample->GetDuration() == 0) { + // update the previous sample + if (dts <= prev_sample->GetDts()) return AP4_ERROR_INVALID_PARAMETERS; + prev_sample->SetDuration((AP4_UI32)(dts-prev_sample->GetDts())); + } else { + if (dts != prev_sample->GetDts()+prev_sample->GetDuration()) { + // mismatch + return AP4_ERROR_INVALID_PARAMETERS; + } + } + } + } + AP4_Sample sample(data_stream, offset, size, duration, description_index, dts, cts_delta, sync); return m_Samples.Append(sample); } /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable::GetSample +| AP4_SyntheticSampleTable::GetSampleIndexForTimeStamp +---------------------------------------------------------------------*/ AP4_Result -AP4_SyntheticSampleTable::GetSampleIndexForTimeStamp(AP4_TimeStamp ts, - AP4_Ordinal& index) +AP4_SyntheticSampleTable::GetSampleIndexForTimeStamp(AP4_UI64 /* ts */, + AP4_Ordinal& /* index */) +{ + return AP4_ERROR_NOT_SUPPORTED; +} + +/*---------------------------------------------------------------------- +| AP4_SyntheticSampleTable::GetNearestSyncSampleIndex ++---------------------------------------------------------------------*/ +AP4_Ordinal +AP4_SyntheticSampleTable::GetNearestSyncSampleIndex(AP4_Ordinal sample_index, bool before) { - return AP4_ERROR_NOT_SUPPORTED_YET; + if (before) { + for (int i=sample_index; i>=0; i--) { + if (m_Samples[i].IsSync()) return i; + } + // not found? + return 0; + } else { + AP4_Cardinal entry_count = m_Samples.ItemCount(); + for (unsigned int i=sample_index; i<entry_count; i++) { + if (m_Samples[i].IsSync()) return i; + } + // not found? + return m_Samples.ItemCount(); + } } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SyntheticSampleTable.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SyntheticSampleTable.h index b57639385..19e364fd4 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SyntheticSampleTable.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4SyntheticSampleTable.h @@ -2,7 +2,7 @@ | | AP4 - Synthetic Sample Table | -| Copyright 2003-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,50 +30,110 @@ #define _AP4_SYNTHETIC_SAMPLE_TABLE_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4Atom.h" #include "Ap4Array.h" +#include "Ap4List.h" +#include "Ap4Sample.h" #include "Ap4SampleTable.h" +#include "Ap4SampleDescription.h" /*---------------------------------------------------------------------- -| forward declarations +| forward declarations +---------------------------------------------------------------------*/ class AP4_ByteStream; /*---------------------------------------------------------------------- -| AP4_SyntheticSampleTable +| constants ++---------------------------------------------------------------------*/ +const AP4_Cardinal AP4_SYNTHETIC_SAMPLE_TABLE_DEFAULT_CHUNK_SIZE = 10; + +/*---------------------------------------------------------------------- +| AP4_SyntheticSampleTable +---------------------------------------------------------------------*/ class AP4_SyntheticSampleTable : public AP4_SampleTable { public: // methods - AP4_SyntheticSampleTable(); + AP4_SyntheticSampleTable(AP4_Cardinal chunk_size + = AP4_SYNTHETIC_SAMPLE_TABLE_DEFAULT_CHUNK_SIZE); virtual ~AP4_SyntheticSampleTable(); // AP4_SampleTable methods virtual AP4_Result GetSample(AP4_Ordinal index, AP4_Sample& sample); virtual AP4_Cardinal GetSampleCount(); + virtual AP4_Result GetSampleChunkPosition(AP4_Ordinal sample_index, + AP4_Ordinal& chunk_index, + AP4_Ordinal& position_in_chunk); virtual AP4_Cardinal GetSampleDescriptionCount(); virtual AP4_SampleDescription* GetSampleDescription(AP4_Ordinal index); - virtual AP4_Result GetSampleIndexForTimeStamp(AP4_TimeStamp ts, - AP4_Ordinal& index); + virtual AP4_Result GetSampleIndexForTimeStamp(AP4_UI64 ts, AP4_Ordinal& index); + virtual AP4_Ordinal GetNearestSyncSampleIndex(AP4_Ordinal index, bool before); // methods - virtual AP4_Result AddSampleDescription(AP4_SampleDescription* description); + /** + * Add a sample description to the sample table. + * Each added sample description will have the next available index, starting at 0 + * + * @param description Pointer to the sample description to add + * @param transfer_ownership Boolean flag indicating whether the ownership of the + * sample description object is transfered to the sample table object (true by default). + * If true, the sample table object will own the sample description object, and will + * delete it when it is itself deleted. If false, the ownership remains with the caller, + * and only a referencing pointer is kept, thus the caller must ensure that the object + * is not deleted before the sample table is deleted. + */ + virtual AP4_Result AddSampleDescription(AP4_SampleDescription* description, + bool transfer_ownership=true); + + /** + * Add a sample to the sample table, where the sample duration is given + * + * @param data_stream The byte stream that contains the sample data. The sample + * object added to the track will keep a reference to that byte stream. + * @param offset Position of the first byte of sample data within the stream + * @param size Size in bytes of the sample data + * @param duration Duration of the sample (in the timescale of the media). This + * value can be 0 if the duration is not known. In that case, the next sample + * added to the table MUST have a non-zero value for the DTS (decoding timestamp), + * which will allow the actual duration of this sample to be computed. + * @param description_index Index of the sample description that applies to + * this sample (typically 0). + * @param dts DTS (decoding timestamp) of the sample. If this value is 0, and there + * already are samples in the table, the DTS of the sample will be automatically + * computed based on the DTS and duration of the preceding sample. If this value is + * not equal to the DTS+duration of the preceding sample, the duration of the + * preceding sample is automatically adjusted, unless it has a non-zero value, in which + * case AP4_ERROR_INVALID_PARAMETERS is returned. + * The DTS of the first sample in the table MUST always be 0. + * @param cts_delta Difference between the CTS (composition/display timestamp) and DTS + * (decoding timestamp) of the sample (in the timescale of the media) + * @param sync Boolean flag indicating whether this is a sync sample or not. + */ virtual AP4_Result AddSample(AP4_ByteStream& data_stream, - AP4_Offset offset, + AP4_Position offset, AP4_Size size, + AP4_UI32 duration, AP4_Ordinal description_index, - AP4_TimeStamp cts = 0, - AP4_TimeStamp dts = 0, - bool sync = false); + AP4_UI64 dts, + AP4_UI32 cts_delta, + bool sync); private: + // classes + class SampleDescriptionHolder { + public: + SampleDescriptionHolder(AP4_SampleDescription* description, bool is_owned) : + m_SampleDescription(description), m_IsOwned(is_owned) {} + ~SampleDescriptionHolder() { if (m_IsOwned) delete m_SampleDescription; } + AP4_SampleDescription* m_SampleDescription; + bool m_IsOwned; + }; + // members - AP4_Array<AP4_Sample> m_Samples; - AP4_List<AP4_SampleDescription> m_SampleDescriptions; + AP4_Array<AP4_Sample> m_Samples; + AP4_List<SampleDescriptionHolder> m_SampleDescriptions; + AP4_Cardinal m_ChunkSize; }; #endif // _AP4_SYNTHETIC_SAMPLE_TABLE_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TimsAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TimsAtom.cpp index 50ab62618..f6f446e7d 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TimsAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TimsAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - tims Atoms | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,34 +27,33 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4TimsAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" #include "Ap4Types.h" /*---------------------------------------------------------------------- -| AP4_TimsAtom::AP4_TimsAtom +| AP4_TimsAtom::AP4_TimsAtom +---------------------------------------------------------------------*/ AP4_TimsAtom::AP4_TimsAtom(AP4_UI32 timescale) : - AP4_Atom(AP4_ATOM_TYPE_TIMS, 4, false), + AP4_Atom(AP4_ATOM_TYPE_TIMS, AP4_ATOM_HEADER_SIZE+4), m_TimeScale(timescale) { } /*---------------------------------------------------------------------- -| AP4_TimsAtom::AP4_TimsAtom +| AP4_TimsAtom::AP4_TimsAtom +---------------------------------------------------------------------*/ -AP4_TimsAtom::AP4_TimsAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_TIMS, size, false, stream) +AP4_TimsAtom::AP4_TimsAtom(AP4_UI32 size, AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_TIMS, size) { stream.ReadUI32(m_TimeScale); } /*---------------------------------------------------------------------- -| AP4_TimsAtom::WriteFields +| AP4_TimsAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_TimsAtom::WriteFields(AP4_ByteStream& stream) @@ -65,7 +64,7 @@ AP4_TimsAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_TimsAtom::InspectFields +| AP4_TimsAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_TimsAtom::InspectFields(AP4_AtomInspector& inspector) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TimsAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TimsAtom.h index 8ae79ab5a..3a78bdc2a 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TimsAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TimsAtom.h @@ -2,7 +2,7 @@ | | AP4 - tims Atoms | -| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,22 +30,23 @@ #define _AP4_TIMS_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4Array.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_TimsAtom +| AP4_TimsAtom +---------------------------------------------------------------------*/ class AP4_TimsAtom : public AP4_Atom { public: + // class methods + static AP4_TimsAtom* Create(AP4_Size size, AP4_ByteStream& stream) { + return new AP4_TimsAtom(size, stream); + } + // methods AP4_TimsAtom(AP4_UI32 timescale); - AP4_TimsAtom(AP4_Size size, AP4_ByteStream& stream); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); @@ -53,6 +54,9 @@ public: virtual AP4_UI32 GetTimeScale() { return m_TimeScale; } private: + // methods + AP4_TimsAtom(AP4_UI32 size, AP4_ByteStream& stream); + // members AP4_UI32 m_TimeScale; }; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TkhdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TkhdAtom.cpp index 560b2bedb..6060ac049 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TkhdAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TkhdAtom.cpp @@ -1,187 +1,211 @@ -/*****************************************************************
-|
-| AP4 - tkhd Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4TkhdAtom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_TkhdAtom::AP4_TkhdAtom
-+---------------------------------------------------------------------*/
-AP4_TkhdAtom::AP4_TkhdAtom(AP4_UI64 creation_time,
- AP4_UI64 modification_time,
- AP4_UI32 track_id,
- AP4_UI64 duration,
- AP4_UI16 volume,
- AP4_UI32 width,
- AP4_UI32 height) :
- AP4_Atom(AP4_ATOM_TYPE_TKHD, 80+AP4_FULL_ATOM_HEADER_SIZE, true),
- m_CreationTime(creation_time),
- m_ModificationTime(modification_time),
- m_TrackId(track_id),
- m_Reserved1(0),
- m_Duration(duration),
- m_Layer(0),
- m_AlternateGroup(0),
- m_Volume(volume),
- m_Reserved3(0),
- m_Width(width),
- m_Height(height)
-{
- m_Flags = AP4_TKHD_FLAG_DEFAULTS;
-
- m_Matrix[0] = 0x00010000;
- m_Matrix[1] = 0;
- m_Matrix[2] = 0;
- m_Matrix[3] = 0;
- m_Matrix[4] = 0x00010000;
- m_Matrix[5] = 0;
- m_Matrix[6] = 0;
- m_Matrix[7] = 0;
- m_Matrix[8] = 0x40000000;
-
- m_Reserved2[0] = 0;
- m_Reserved2[1] = 0;
-}
-
-/*----------------------------------------------------------------------
-| AP4_TkhdAtom::AP4_TkhdAtom
-+---------------------------------------------------------------------*/
-AP4_TkhdAtom::AP4_TkhdAtom(AP4_Size size, AP4_ByteStream& stream) :
- AP4_Atom(AP4_ATOM_TYPE_TKHD, size, true, stream)
-{
- if (m_Version == 0) {
- AP4_UI32 tmp = 0;
- stream.ReadUI32(tmp); m_CreationTime = tmp;
- stream.ReadUI32(tmp); m_ModificationTime = tmp;
- stream.ReadUI32(m_TrackId);
- stream.ReadUI32(m_Reserved1);
- stream.ReadUI32(tmp); m_Duration = tmp;
- } else if (m_Version == 1) {
- stream.ReadUI64(m_CreationTime);
- stream.ReadUI64(m_ModificationTime);
- stream.ReadUI32(m_TrackId);
- stream.ReadUI32(m_Reserved1);
- stream.ReadUI64(m_Duration);
- } else {
- // TODO
- }
-
- stream.Read((void*)m_Reserved2, 8, NULL);
- stream.ReadUI16(m_Layer);
- stream.ReadUI16(m_AlternateGroup);
- stream.ReadUI16(m_Volume);
- stream.ReadUI16(m_Reserved3);
- for (int i=0; i<9; i++) {
- stream.ReadUI32(m_Matrix[i]);
- }
- stream.ReadUI32(m_Width);
- stream.ReadUI32(m_Height);
-}
-
-/*----------------------------------------------------------------------
-| AP4_TkhdAtom::WriteFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_TkhdAtom::WriteFields(AP4_ByteStream& stream)
-{
- AP4_Result result;
-
- // creation/modification time, track id, reserved1 & duration
- if (m_Version == 0) {
- result = stream.WriteUI32((AP4_UI32)m_CreationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32((AP4_UI32)m_ModificationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_TrackId);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_Reserved1);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32((AP4_UI32)m_Duration);
- if (AP4_FAILED(result)) return result;
- } else if (m_Version == 1) {
- result = stream.WriteUI64(m_CreationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI64(m_ModificationTime);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_TrackId);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_Reserved1);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI64(m_Duration);
- if (AP4_FAILED(result)) return result;
- } else {
- // TODO
- }
-
- // reserved2
- result = stream.Write(m_Reserved2, sizeof(m_Reserved2));
- if (AP4_FAILED(result)) return result;
-
- // layer, alternate group & volume
- result = stream.WriteUI16(m_Layer);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI16(m_AlternateGroup);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI16(m_Volume);
- if (AP4_FAILED(result)) return result;
-
- // reserved3
- result = stream.WriteUI16(m_Reserved3);
-
- // matrix
- for (int i=0; i<9; i++) {
- result = stream.WriteUI32(m_Matrix[i]);
- if (AP4_FAILED(result)) return result;
- }
-
- // width & height
- result = stream.WriteUI32(m_Width);
- if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_Height);
- if (AP4_FAILED(result)) return result;
-
- return result;
-}
-
-/*----------------------------------------------------------------------
-| AP4_TkhdAtom::InspectFields
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_TkhdAtom::InspectFields(AP4_AtomInspector& inspector)
-{
- inspector.AddField("enabled", ((m_Flags & AP4_TKHD_FLAG_TRACK_ENABLED) ? 1 : 0), AP4_AtomInspector::HINT_BOOLEAN);
- inspector.AddField("id", m_TrackId);
- inspector.AddField("duration", (AP4_UI32)m_Duration);
-
- return AP4_SUCCESS;
-}
+/***************************************************************** +| +| AP4 - tkhd 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 "Ap4TkhdAtom.h" +#include "Ap4AtomFactory.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_TkhdAtom) + +/*---------------------------------------------------------------------- +| AP4_TkhdAtom::Create ++---------------------------------------------------------------------*/ +AP4_TkhdAtom* +AP4_TkhdAtom::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 > 1) return NULL; + return new AP4_TkhdAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_TkhdAtom::AP4_TkhdAtom ++---------------------------------------------------------------------*/ +AP4_TkhdAtom::AP4_TkhdAtom(AP4_UI32 creation_time, + AP4_UI32 modification_time, + AP4_UI32 track_id, + AP4_UI64 duration, + AP4_UI16 volume, + AP4_UI32 width, + AP4_UI32 height) : + AP4_Atom(AP4_ATOM_TYPE_TKHD, AP4_FULL_ATOM_HEADER_SIZE+80, 0, 0), + m_CreationTime(creation_time), + m_ModificationTime(modification_time), + m_TrackId(track_id), + m_Reserved1(0), + m_Duration(duration), + m_Layer(0), + m_AlternateGroup(0), + m_Volume(volume), + m_Reserved3(0), + m_Width(width), + m_Height(height) +{ + m_Flags = AP4_TKHD_FLAG_DEFAULTS; + + m_Matrix[0] = 0x00010000; + m_Matrix[1] = 0; + m_Matrix[2] = 0; + m_Matrix[3] = 0; + m_Matrix[4] = 0x00010000; + m_Matrix[5] = 0; + m_Matrix[6] = 0; + m_Matrix[7] = 0; + m_Matrix[8] = 0x40000000; + + m_Reserved2[0] = 0; + m_Reserved2[1] = 0; +} + +/*---------------------------------------------------------------------- +| AP4_TkhdAtom::AP4_TkhdAtom ++---------------------------------------------------------------------*/ +AP4_TkhdAtom::AP4_TkhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_TKHD, size, version, flags) +{ + if (m_Version == 0) { + // we only deal with version 0 for now + AP4_UI32 creation_time; + stream.ReadUI32(creation_time); + m_CreationTime = creation_time; + AP4_UI32 modification_time; + stream.ReadUI32(modification_time); + m_ModificationTime = modification_time; + stream.ReadUI32(m_TrackId); + stream.ReadUI32(m_Reserved1); + AP4_UI32 duration; + stream.ReadUI32(duration); + m_Duration = duration; + } else { + stream.ReadUI64(m_CreationTime); + stream.ReadUI64(m_ModificationTime); + stream.ReadUI32(m_TrackId); + stream.ReadUI32(m_Reserved1); + stream.ReadUI64(m_Duration); + } + + stream.Read((void*)m_Reserved2, 8); + stream.ReadUI16(m_Layer); + stream.ReadUI16(m_AlternateGroup); + stream.ReadUI16(m_Volume); + stream.ReadUI16(m_Reserved3); + for (int i=0; i<9; i++) { + stream.ReadUI32(m_Matrix[i]); + } + stream.ReadUI32(m_Width); + stream.ReadUI32(m_Height); +} + +/*---------------------------------------------------------------------- +| AP4_TkhdAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TkhdAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_Result result; + + // creation/modification time, track id, reserved1 & duration + if (m_Version == 0) { + result = stream.WriteUI32((AP4_UI32)m_CreationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32((AP4_UI32)m_ModificationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_TrackId); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_Reserved1); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32((AP4_UI32)m_Duration); + if (AP4_FAILED(result)) return result; + } else { + result = stream.WriteUI64(m_CreationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI64(m_ModificationTime); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_TrackId); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_Reserved1); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI64(m_Duration); + if (AP4_FAILED(result)) return result; + } + + // reserved2 + result = stream.Write(m_Reserved2, sizeof(m_Reserved2)); + if (AP4_FAILED(result)) return result; + + // layer, alternate group & volume + result = stream.WriteUI16(m_Layer); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI16(m_AlternateGroup); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI16(m_Volume); + if (AP4_FAILED(result)) return result; + + // reserved3 + result = stream.WriteUI16(m_Reserved3); + + // matrix + for (int i=0; i<9; i++) { + result = stream.WriteUI32(m_Matrix[i]); + if (AP4_FAILED(result)) return result; + } + + // width & height + result = stream.WriteUI32(m_Width); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI32(m_Height); + if (AP4_FAILED(result)) return result; + + return result; +} + +/*---------------------------------------------------------------------- +| AP4_TkhdAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TkhdAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("enabled", ((m_Flags & AP4_TKHD_FLAG_TRACK_ENABLED) ? 1 : 0), AP4_AtomInspector::HINT_BOOLEAN); + inspector.AddField("id", m_TrackId); + inspector.AddField("duration", m_Duration); + inspector.AddFieldF("width", (float)m_Width/65536.0f); + inspector.AddFieldF("height", (float)m_Height/65536.0f); + + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TkhdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TkhdAtom.h index 37b5c270f..d0d0f7b68 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TkhdAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TkhdAtom.h @@ -1,105 +1,106 @@ -/*****************************************************************
-|
-| AP4 - tkhd Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_TKHD_ATOM_H_
-#define _AP4_TKHD_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4List.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| constants
-+---------------------------------------------------------------------*/
-const int AP4_TKHD_FLAG_TRACK_ENABLED = 1;
-const int AP4_TKHD_FLAG_TRACK_IN_MOVIE = 2;
-const int AP4_TKHD_FLAG_TRACK_IN_PREVIEW = 4;
-
-const int AP4_TKHD_FLAG_DEFAULTS = 7;
-
-/*----------------------------------------------------------------------
-| AP4_TkhdAtom
-+---------------------------------------------------------------------*/
-class AP4_TkhdAtom : public AP4_Atom
-{
-public:
- // methods
- AP4_TkhdAtom(AP4_UI64 creation_time,
- AP4_UI64 modification_time,
- AP4_UI32 track_id,
- AP4_UI64 duration,
- AP4_UI16 volume,
- AP4_UI32 width,
- AP4_UI32 height);
- AP4_TkhdAtom(AP4_Size size, AP4_ByteStream& stream);
- virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
- virtual AP4_Result WriteFields(AP4_ByteStream& stream);
-
- AP4_UI64 GetDuration() { return m_Duration; }
- AP4_Result SetDuration(AP4_UI64 duration) {
- m_Duration = duration;
- return AP4_SUCCESS;
- }
- AP4_UI32 GetTrackId() { return m_TrackId; }
- AP4_Result SetTrackId(AP4_UI32 track_id) {
- m_TrackId = track_id;
- return AP4_SUCCESS;
- }
-
- void GetTranslation(AP4_Float& x, AP4_Float& y)
- {
- x = (AP4_Float)(*(int*)&m_Matrix[6]) / 65536;
- y = (AP4_Float)(*(int*)&m_Matrix[7]) / 65536;
- }
-
- AP4_UI32 GetWidth() const {return m_Width;}
- AP4_UI32 GetHeight() const {return m_Height;}
-
- private:
- // members
- AP4_UI64 m_CreationTime;
- AP4_UI64 m_ModificationTime;
- AP4_UI32 m_TrackId;
- AP4_UI32 m_Reserved1;
- AP4_UI64 m_Duration;
- AP4_UI08 m_DataVersion1[32];
- AP4_UI32 m_Reserved2[2];
- AP4_UI16 m_Layer;
- AP4_UI16 m_AlternateGroup;
- AP4_UI16 m_Volume;
- AP4_UI16 m_Reserved3;
- AP4_UI32 m_Matrix[9];
- AP4_UI32 m_Width;
- AP4_UI32 m_Height;
-};
-
-#endif // _AP4_TKHD_ATOM_H_
+/***************************************************************** +| +| AP4 - tkhd 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_TKHD_ATOM_H_ +#define _AP4_TKHD_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int AP4_TKHD_FLAG_TRACK_ENABLED = 1; +const int AP4_TKHD_FLAG_TRACK_IN_MOVIE = 2; +const int AP4_TKHD_FLAG_TRACK_IN_PREVIEW = 4; + +const int AP4_TKHD_FLAG_DEFAULTS = 7; + +/*---------------------------------------------------------------------- +| AP4_TkhdAtom ++---------------------------------------------------------------------*/ +class AP4_TkhdAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_TkhdAtom, AP4_Atom) + + // class methods + static AP4_TkhdAtom* Create(AP4_Size size, AP4_ByteStream& stream); + + // methods + AP4_TkhdAtom(AP4_UI32 creation_time, + AP4_UI32 modification_time, + AP4_UI32 track_id, + AP4_UI64 duration, + AP4_UI16 volume, + AP4_UI32 width, + AP4_UI32 height); + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + AP4_UI64 GetDuration() { return m_Duration; } + void SetDuration(AP4_UI64 duration) { m_Duration = duration; } + AP4_UI32 GetTrackId() { return m_TrackId; } + void SetTrackId(AP4_UI32 track_id) { m_TrackId = track_id; } + + void GetTranslation(float& x, float& y) { + x = (float)(*(int*)&m_Matrix[6]) / 65536; + y = (float)(*(int*)&m_Matrix[7]) / 65536; + } + + AP4_UI32 GetWidth() { return m_Width; } + void SetWidth(AP4_UI32 width) { m_Width = width; } + AP4_UI32 GetHeight() { return m_Height; } + void SetHeight(AP4_UI32 height) { m_Height = height; } + + private: + // methods + AP4_TkhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // members + AP4_UI64 m_CreationTime; + AP4_UI64 m_ModificationTime; + AP4_UI32 m_TrackId; + AP4_UI32 m_Reserved1; + AP4_UI64 m_Duration; + AP4_UI32 m_Reserved2[2]; + AP4_UI16 m_Layer; + AP4_UI16 m_AlternateGroup; + AP4_UI16 m_Volume; + AP4_UI16 m_Reserved3; + AP4_UI32 m_Matrix[9]; + AP4_UI32 m_Width; + AP4_UI32 m_Height; +}; + +#endif // _AP4_TKHD_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Track.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Track.cpp index 32e58baef..9dc915571 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Track.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Track.cpp @@ -1,357 +1,471 @@ -/*****************************************************************
-|
-| AP4 - Track Objects
-|
-| Copyright 2002 Gilles Boccon-Gibod & Julien Boeuf
-|
-|
-| 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 "Ap4ByteStream.h"
-#include "Ap4HdlrAtom.h"
-#include "Ap4MvhdAtom.h"
-#include "Ap4Track.h"
-#include "Ap4Utils.h"
-#include "Ap4Sample.h"
-#include "Ap4DataBuffer.h"
-#include "Ap4TrakAtom.h"
-#include "Ap4MoovAtom.h"
-#include "Ap4AtomSampleTable.h"
-#include "Ap4SdpAtom.h"
-#include "Ap4MdhdAtom.h"
-
-/*----------------------------------------------------------------------
-| AP4_Track::AP4_Track
-+---------------------------------------------------------------------*/
-AP4_Track::AP4_Track(Type type,
- AP4_SampleTable* sample_table,
- AP4_UI32 track_id,
- AP4_UI32 movie_time_scale,
- AP4_UI32 media_time_scale,
- AP4_UI64 media_duration,
- const char* language,
- AP4_UI32 width,
- AP4_UI32 height) :
- m_TrakAtomIsOwned(true),
- m_Type(type),
- m_SampleTable(sample_table),
- m_SampleTableIsOwned(false),
- m_MovieTimeScale(movie_time_scale ?
- movie_time_scale :
- AP4_TRACK_DEFAULT_MOVIE_TIMESCALE),
- m_MediaTimeScale(media_time_scale)
-{
- // compute the default volume value
- unsigned int volume = 0;
- if (type == TYPE_AUDIO) volume = 0x100;
-
- // compute the handler type and name
- AP4_Atom::Type hdlr_type;
- const char* hdlr_name;
- switch (type) {
- case TYPE_AUDIO:
- hdlr_type = AP4_HANDLER_TYPE_SOUN;
- hdlr_name = "Bento4 Sound Handler";
- break;
-
- case TYPE_VIDEO:
- hdlr_type = AP4_HANDLER_TYPE_VIDE;
- hdlr_name = "Bento4 Video Handler";
- break;
-
- case TYPE_HINT:
- hdlr_type = AP4_HANDLER_TYPE_HINT;
- hdlr_name = "Bento4 Hint Handler";
- break;
-
- default:
- hdlr_type = 0;
- hdlr_name = NULL;
- break;
- }
-
- // compute the track duration in units of the movie time scale
- AP4_UI64 track_duration = AP4_ConvertTime(media_duration,
- media_time_scale,
- movie_time_scale);
-
- // create a trak atom
- m_TrakAtom = DNew AP4_TrakAtom(sample_table,
- hdlr_type,
- hdlr_name,
- track_id,
- 0,
- 0,
- track_duration,
- media_time_scale,
- media_duration,
- volume,
- language,
- width,
- height);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::AP4_Track
-+---------------------------------------------------------------------*/
-AP4_Track::AP4_Track(AP4_TrakAtom& atom,
- AP4_ByteStream& sample_stream,
- AP4_UI32 movie_time_scale) :
- m_TrakAtom(&atom),
- m_TrakAtomIsOwned(false),
- m_Type(TYPE_UNKNOWN),
- m_SampleTable(NULL),
- m_SampleTableIsOwned(true),
- m_MovieTimeScale(movie_time_scale),
- m_MediaTimeScale(0)
-{
- // find the handler type
- AP4_Atom* sub = atom.FindChild("mdia/hdlr");
- if (sub) {
- AP4_HdlrAtom* hdlr = dynamic_cast<AP4_HdlrAtom*>(sub);
- if (hdlr) {
- AP4_Atom::Type type = hdlr->GetHandlerType();
- if (type == AP4_HANDLER_TYPE_SOUN) {
- m_Type = TYPE_AUDIO;
- } else if (type == AP4_HANDLER_TYPE_VIDE) {
- m_Type = TYPE_VIDEO;
- } else if (type == AP4_HANDLER_TYPE_TEXT) {
- m_Type = TYPE_TEXT;
- } else if (type == AP4_HANDLER_TYPE_TX3G) {
- m_Type = TYPE_TEXT;
- } else if (type == AP4_HANDLER_TYPE_SUBP) {
- m_Type = TYPE_SUBP;
- } else if (type == AP4_HANDLER_TYPE_HINT) {
- m_Type = TYPE_HINT;
- }
- }
- }
-
- // get the media time scale
- sub = atom.FindChild("mdia/mdhd");
- if (sub) {
- AP4_MdhdAtom* mdhd = dynamic_cast<AP4_MdhdAtom*>(sub);
- if (mdhd) {
- m_MediaTimeScale = mdhd->GetTimeScale();
- }
- }
-
- // create a facade for the stbl atom
- AP4_ContainerAtom* stbl = dynamic_cast<AP4_ContainerAtom*>(
- atom.FindChild("mdia/minf/stbl"));
- if (stbl) {
- m_SampleTable = DNew AP4_AtomSampleTable(stbl, sample_stream);
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::~AP4_Track
-+---------------------------------------------------------------------*/
-AP4_Track::~AP4_Track()
-{
- if (m_TrakAtomIsOwned) delete m_TrakAtom;
- if (m_SampleTableIsOwned) delete m_SampleTable;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetId
-+---------------------------------------------------------------------*/
-AP4_UI32
-AP4_Track::GetId()
-{
- return m_TrakAtom->GetId();
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::SetId
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Track::SetId(AP4_UI32 id)
-{
- m_TrakAtom->SetId(id);
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetDuration
-+---------------------------------------------------------------------*/
-AP4_UI64
-AP4_Track::GetDuration()
-{
- return m_TrakAtom->GetDuration();
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetDurationMs
-+---------------------------------------------------------------------*/
-AP4_Duration
-AP4_Track::GetDurationMs()
-{
- AP4_UI64 duration = m_TrakAtom->GetDuration();
- return AP4_DurationMsFromUnits(duration, m_MovieTimeScale);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetSampleCount
-+---------------------------------------------------------------------*/
-AP4_Cardinal
-AP4_Track::GetSampleCount()
-{
- // delegate to the sample table
- return m_SampleTable ? m_SampleTable->GetSampleCount() : 0;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetSample
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Track::GetSample(AP4_Ordinal index, AP4_Sample& sample)
-{
- // delegate to the sample table
- return m_SampleTable ? m_SampleTable->GetSample(index, sample) : AP4_FAILURE;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetSampleDescription
-+---------------------------------------------------------------------*/
-AP4_SampleDescription*
-AP4_Track::GetSampleDescription(AP4_Ordinal index)
-{
- // delegate to the sample table
- return m_SampleTable ? m_SampleTable->GetSampleDescription(index) : NULL;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::ReadSample
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Track::ReadSample(AP4_Ordinal index,
- AP4_Sample& sample,
- AP4_DataBuffer& data)
-{
- AP4_Result result;
-
- // get the sample
- result = GetSample(index, sample);
- if (AP4_FAILED(result)) return result;
-
- // read the data
- return sample.ReadData(data);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetSampleIndexForTimeStampMs
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Track::GetSampleIndexForTimeStampMs(AP4_TimeStamp ts, AP4_Ordinal& index)
-{
- // convert the ts in the timescale of the track's media
- ts = AP4_ConvertTime(ts, 1000, m_MediaTimeScale);
-
- return m_SampleTable->GetSampleIndexForTimeStamp(ts, index);
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::SetMovieTimeScale
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_Track::SetMovieTimeScale(AP4_UI32 time_scale)
-{
- // check that we can convert
- if (m_MovieTimeScale == 0) return AP4_FAILURE;
-
- // convert from one time scale to the other
- m_TrakAtom->SetDuration(AP4_ConvertTime(m_TrakAtom->GetDuration(),
- m_MovieTimeScale,
- time_scale));
-
- // keep the new movie timescale
- m_MovieTimeScale = time_scale;
-
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetMediaTimeScale
-+---------------------------------------------------------------------*/
-AP4_UI32
-AP4_Track::GetMediaTimeScale()
-{
- return m_MediaTimeScale;
-}
-
-// save the implementation for later
-#if 0
-/*----------------------------------------------------------------------
-| AP4_HintTrack::SetSdpText
-+---------------------------------------------------------------------*/
-void
-AP4_HintTrack::SetSdpText(const char* text)
-{
- // build an sdp atom
- AP4_SdpAtom* sdp = DNew AP4_SdpAtom(text);
-
- // build the hnti
- AP4_ContainerAtom* hnti = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_HNTI);
- hnti->AddChild(sdp);
-
- // check if there's already a user data atom
- AP4_ContainerAtom* udta = dynamic_cast<AP4_ContainerAtom*>(m_TrakAtom->FindChild("udta"));
- if (udta == NULL) {
- // otherwise create it
- udta = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_UDTA);
- m_TrakAtom->AddChild(udta);
- }
- udta->AddChild(hnti);
-}
-
-#endif
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetTrackName
-+---------------------------------------------------------------------*/
-
-AP4_String
-AP4_Track::GetTrackName()
-{
- AP4_String TrackName;
- if(AP4_HdlrAtom* hdlr = dynamic_cast<AP4_HdlrAtom*>(m_TrakAtom->FindChild("mdia/hdlr")))
- TrackName = hdlr->GetHandlerName();
- return TrackName;
-}
-
-/*----------------------------------------------------------------------
-| AP4_Track::GetTrackLanguage
-+---------------------------------------------------------------------*/
-
-AP4_String
-AP4_Track::GetTrackLanguage()
-{
- AP4_String TrackLanguage;
- if(AP4_MdhdAtom* mdhd = dynamic_cast<AP4_MdhdAtom*>(m_TrakAtom->FindChild("mdia/mdhd")))
- TrackLanguage = mdhd->GetLanguage().c_str();
- return TrackLanguage;
-}
+/***************************************************************** +| +| AP4 - Track Objects +| +| 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 "Ap4ByteStream.h" +#include "Ap4HdlrAtom.h" +#include "Ap4MvhdAtom.h" +#include "Ap4Track.h" +#include "Ap4Utils.h" +#include "Ap4Sample.h" +#include "Ap4DataBuffer.h" +#include "Ap4TrakAtom.h" +#include "Ap4TkhdAtom.h" +#include "Ap4MoovAtom.h" +#include "Ap4AtomSampleTable.h" +#include "Ap4SdpAtom.h" +#include "Ap4MdhdAtom.h" +#include "Ap4SyntheticSampleTable.h" + +/*---------------------------------------------------------------------- +| AP4_Track::AP4_Track ++---------------------------------------------------------------------*/ +AP4_Track::AP4_Track(Type type, + AP4_SampleTable* sample_table, + AP4_UI32 track_id, + AP4_UI32 movie_time_scale, + AP4_UI64 track_duration, + AP4_UI32 media_time_scale, + AP4_UI64 media_duration, + const char* language, + AP4_UI32 width, + AP4_UI32 height) : + m_TrakAtomIsOwned(true), + m_Type(type), + m_SampleTable(sample_table), + m_SampleTableIsOwned(true), + m_MovieTimeScale(movie_time_scale ? + movie_time_scale : + AP4_TRACK_DEFAULT_MOVIE_TIMESCALE) +{ + // compute the default volume value + unsigned int volume = 0; + if (type == TYPE_AUDIO) volume = 0x100; + + // compute the handler type and name + AP4_Atom::Type hdlr_type; + const char* hdlr_name; + switch (type) { + case TYPE_AUDIO: + hdlr_type = AP4_HANDLER_TYPE_SOUN; + hdlr_name = "Bento4 Sound Handler"; + break; + + case TYPE_VIDEO: + hdlr_type = AP4_HANDLER_TYPE_VIDE; + hdlr_name = "Bento4 Video Handler"; + break; + + case TYPE_HINT: + hdlr_type = AP4_HANDLER_TYPE_HINT; + hdlr_name = "Bento4 Hint Handler"; + break; + + case TYPE_TEXT: + hdlr_type = AP4_HANDLER_TYPE_TEXT; + hdlr_name = "Bento4 Text Handler"; + break; + + default: + hdlr_type = 0; + hdlr_name = NULL; + break; + } + + // create a trak atom + m_TrakAtom = new AP4_TrakAtom(sample_table, + hdlr_type, + hdlr_name, + track_id, + 0, + 0, + track_duration, + media_time_scale, + media_duration, + volume, + language, + width, + height); +} + +/*---------------------------------------------------------------------- +| AP4_Track::AP4_Track ++---------------------------------------------------------------------*/ +AP4_Track::AP4_Track(AP4_TrakAtom& atom, + AP4_ByteStream& sample_stream, + AP4_UI32 movie_time_scale) : + m_TrakAtom(&atom), + m_TrakAtomIsOwned(false), + m_Type(TYPE_UNKNOWN), + m_SampleTable(NULL), + m_SampleTableIsOwned(true), + m_MovieTimeScale(movie_time_scale) +{ + // find the handler type + AP4_Atom* sub = atom.FindChild("mdia/hdlr"); + if (sub) { + AP4_HdlrAtom* hdlr = AP4_DYNAMIC_CAST(AP4_HdlrAtom, sub); + if (hdlr) { + AP4_UI32 type = hdlr->GetHandlerType(); + if (type == AP4_HANDLER_TYPE_SOUN) { + m_Type = TYPE_AUDIO; + } else if (type == AP4_HANDLER_TYPE_VIDE) { + m_Type = TYPE_VIDEO; + } else if (type == AP4_HANDLER_TYPE_HINT) { + m_Type = TYPE_HINT; + } else if (type == AP4_HANDLER_TYPE_ODSM || + type == AP4_HANDLER_TYPE_SDSM) { + m_Type = TYPE_SYSTEM; + } else if (type == AP4_HANDLER_TYPE_TEXT || + type == AP4_HANDLER_TYPE_TX3G) { + m_Type = TYPE_TEXT; + } else if (type == AP4_HANDLER_TYPE_JPEG) { + m_Type = TYPE_JPEG; + // ==> Start patch MPC + } else if (type == AP4_HANDLER_TYPE_SUBP) { + m_Type = TYPE_SUBP; + // <== End patch MPC + } + } + } + + // create a facade for the stbl atom + AP4_ContainerAtom* stbl = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom.FindChild("mdia/minf/stbl")); + if (stbl) { + m_SampleTable = new AP4_AtomSampleTable(stbl, sample_stream); + } +} + +/*---------------------------------------------------------------------- +| AP4_Track::~AP4_Track ++---------------------------------------------------------------------*/ +AP4_Track::~AP4_Track() +{ + if (m_TrakAtomIsOwned) delete m_TrakAtom; + if (m_SampleTableIsOwned) delete m_SampleTable; +} + +/*---------------------------------------------------------------------- +| AP4_Track::Clone ++---------------------------------------------------------------------*/ +AP4_Track* +AP4_Track::Clone(AP4_Result* result) +{ + AP4_SyntheticSampleTable* sample_table = new AP4_SyntheticSampleTable(); + + // default return value + if (result) *result = AP4_SUCCESS; + + // add clones of the sample descriptions to the new sample table + for (unsigned int i=0; ;i++) { + AP4_SampleDescription* sample_description = GetSampleDescription(i); + if (sample_description == NULL) break; + sample_table->AddSampleDescription(sample_description->Clone()); + } + + AP4_Sample sample; + AP4_Ordinal index = 0; + while (AP4_SUCCEEDED(GetSample(index, sample))) { + AP4_ByteStream* data_stream; + data_stream = sample.GetDataStream(); + sample_table->AddSample(*data_stream, + sample.GetOffset(), + sample.GetSize(), + sample.GetDuration(), + sample.GetDescriptionIndex(), + sample.GetDts(), + sample.GetCtsDelta(), + sample.IsSync()); + AP4_RELEASE(data_stream); // release our ref, the table has kept its own ref. + index++; + } + + // create the cloned track + AP4_Track* clone = new AP4_Track(GetType(), + sample_table, + GetId(), + GetMovieTimeScale(), + GetDuration(), + GetMediaTimeScale(), + GetMediaDuration(), + GetTrackLanguage().GetChars(), + GetWidth(), + GetHeight()); + + return clone; +} + +/*---------------------------------------------------------------------- +| AP4_Track::Attach ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Track::Attach(AP4_MoovAtom* moov) +{ + if (!m_TrakAtomIsOwned) return AP4_ERROR_INTERNAL; + moov->AddChild(m_TrakAtom); + m_TrakAtomIsOwned = false; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetFlags ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_Track::GetFlags() +{ + if (m_TrakAtom) { + AP4_TkhdAtom* tkhd = AP4_DYNAMIC_CAST(AP4_TkhdAtom, m_TrakAtom->FindChild("tkhd")); + if (tkhd) { + return tkhd->GetFlags(); + } + } + return 0; +} + +/*---------------------------------------------------------------------- +| AP4_Track::SetFlags ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Track::SetFlags(AP4_UI32 flags) +{ + if (m_TrakAtom) { + AP4_TkhdAtom* tkhd = AP4_DYNAMIC_CAST(AP4_TkhdAtom, m_TrakAtom->FindChild("tkhd")); + if (tkhd) { + tkhd->SetFlags(flags); + return AP4_SUCCESS; + } + } + return AP4_ERROR_INVALID_STATE; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetHandlerType ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_Track::GetHandlerType() +{ + if (m_TrakAtom) { + AP4_HdlrAtom* hdlr = AP4_DYNAMIC_CAST(AP4_HdlrAtom, m_TrakAtom->FindChild("mdia/hdlr")); + if (hdlr) { + return hdlr->GetHandlerType(); + } + } + return 0; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetId ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_Track::GetId() +{ + return m_TrakAtom->GetId(); +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetWidth ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_Track::GetWidth() +{ + return m_TrakAtom->GetWidth(); +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetHeight ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_Track::GetHeight() +{ + return m_TrakAtom->GetHeight(); +} + +/*---------------------------------------------------------------------- +| AP4_Track::SetId ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Track::SetId(AP4_UI32 id) +{ + m_TrakAtom->SetId(id); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetDuration ++---------------------------------------------------------------------*/ +AP4_UI64 +AP4_Track::GetDuration() +{ + return m_TrakAtom->GetDuration(); +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetDurationMs ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_Track::GetDurationMs() +{ + AP4_UI64 duration = m_TrakAtom->GetDuration(); + return AP4_DurationMsFromUnits(duration, m_MovieTimeScale); +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetSampleCount ++---------------------------------------------------------------------*/ +AP4_Cardinal +AP4_Track::GetSampleCount() +{ + // delegate to the sample table + return m_SampleTable ? m_SampleTable->GetSampleCount() : 0; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetSample ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Track::GetSample(AP4_Ordinal index, AP4_Sample& sample) +{ + // delegate to the sample table + return m_SampleTable ? m_SampleTable->GetSample(index, sample) : AP4_FAILURE; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetSampleDescription ++---------------------------------------------------------------------*/ +AP4_SampleDescription* +AP4_Track::GetSampleDescription(AP4_Ordinal index) +{ + // delegate to the sample table + return m_SampleTable ? m_SampleTable->GetSampleDescription(index) : NULL; +} + +/*---------------------------------------------------------------------- +| AP4_Track::ReadSample ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Track::ReadSample(AP4_Ordinal index, + AP4_Sample& sample, + AP4_DataBuffer& data) +{ + AP4_Result result; + + // get the sample + result = GetSample(index, sample); + if (AP4_FAILED(result)) return result; + + // read the data + return sample.ReadData(data); +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetSampleIndexForTimeStampMs ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Track::GetSampleIndexForTimeStampMs(AP4_UI32 ts_ms, AP4_Ordinal& index) +{ + // convert the ts in the timescale of the track's media + AP4_UI64 ts = AP4_ConvertTime(ts_ms, 1000, GetMediaTimeScale()); + + return m_SampleTable->GetSampleIndexForTimeStamp(ts, index); +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetNearestSyncSampleIndex ++---------------------------------------------------------------------*/ +AP4_Ordinal +AP4_Track::GetNearestSyncSampleIndex(AP4_Ordinal index, bool before /* = true */) +{ + if (m_SampleTable == NULL) return index; + return m_SampleTable->GetNearestSyncSampleIndex(index, before); +} + +/*---------------------------------------------------------------------- +| AP4_Track::SetMovieTimeScale ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Track::SetMovieTimeScale(AP4_UI32 time_scale) +{ + // check that we can convert + if (m_MovieTimeScale == 0) return AP4_FAILURE; + + // convert from one time scale to the other + m_TrakAtom->SetDuration(AP4_ConvertTime(m_TrakAtom->GetDuration(), + m_MovieTimeScale, + time_scale)); + + // keep the new movie timescale + m_MovieTimeScale = time_scale; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetMediaTimeScale ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_Track::GetMediaTimeScale() +{ + return m_TrakAtom?m_TrakAtom->GetMediaTimeScale():0; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetMediaDuration ++---------------------------------------------------------------------*/ +AP4_UI64 +AP4_Track::GetMediaDuration() +{ + return m_TrakAtom?m_TrakAtom->GetMediaDuration():0; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetTrackName ++---------------------------------------------------------------------*/ +const AP4_String +AP4_Track::GetTrackName() +{ + if (AP4_HdlrAtom* hdlr = AP4_DYNAMIC_CAST(AP4_HdlrAtom, m_TrakAtom->FindChild("mdia/hdlr"))) { + return hdlr->GetHandlerName(); + } + return NULL; +} + +/*---------------------------------------------------------------------- +| AP4_Track::GetTrackLanguage ++---------------------------------------------------------------------*/ +const AP4_String +AP4_Track::GetTrackLanguage() +{ + if (AP4_MdhdAtom* mdhd = AP4_DYNAMIC_CAST(AP4_MdhdAtom, m_TrakAtom->FindChild("mdia/mdhd"))) { + return mdhd->GetLanguage(); + } + return NULL; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Track.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Track.h index 4b901e159..d169ead03 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Track.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Track.h @@ -1,115 +1,141 @@ -/*****************************************************************
-|
-| AP4 - Track Objects
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_TRAK_H_
-#define _AP4_TRAK_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4Array.h"
-#include "Ap4SampleDescription.h"
-#include "Ap4SampleTable.h"
-
-/*----------------------------------------------------------------------
-| forward declarations
-+---------------------------------------------------------------------*/
-class AP4_StblAtom;
-class AP4_ByteStream;
-class AP4_Sample;
-class AP4_DataBuffer;
-class AP4_TrakAtom;
-class AP4_MoovAtom;
-
-/*----------------------------------------------------------------------
-| constants
-+---------------------------------------------------------------------*/
-const AP4_UI32 AP4_TRACK_DEFAULT_MOVIE_TIMESCALE = 1000;
-
-/*----------------------------------------------------------------------
-| AP4_Track
-+---------------------------------------------------------------------*/
-class AP4_Track {
- public:
- // types
- typedef enum {
- TYPE_UNKNOWN,
- TYPE_AUDIO,
- TYPE_VIDEO,
- TYPE_TEXT,
- TYPE_SUBP,
- TYPE_HINT
- } Type;
-
- // methods
- AP4_Track(Type type,
- AP4_SampleTable* sample_table,
- AP4_UI32 track_id,
- AP4_UI32 movie_time_scale, // 0 = use default
- AP4_UI32 media_time_scale,
- AP4_UI64 media_duration,
- const char* language,
- AP4_UI32 width,
- AP4_UI32 height);
- AP4_Track(AP4_TrakAtom& atom,
- AP4_ByteStream& sample_stream,
- AP4_UI32 movie_time_scale);
- virtual ~AP4_Track();
- AP4_Track::Type GetType() { return m_Type; }
- AP4_UI64 GetDuration();
- AP4_Duration GetDurationMs();
- AP4_Cardinal GetSampleCount();
- AP4_Result GetSample(AP4_Ordinal index, AP4_Sample& sample);
- AP4_Result ReadSample(AP4_Ordinal index,
- AP4_Sample& sample,
- AP4_DataBuffer& data);
- AP4_Result GetSampleIndexForTimeStampMs(AP4_TimeStamp ts,
- AP4_Ordinal& index);
- AP4_SampleDescription* GetSampleDescription(AP4_Ordinal index);
- AP4_UI32 GetId();
- AP4_Result SetId(AP4_UI32 track_id);
- AP4_TrakAtom* GetTrakAtom() { return m_TrakAtom; }
- AP4_Result SetMovieTimeScale(AP4_UI32 time_scale);
- AP4_UI32 GetMediaTimeScale();
-
- AP4_String GetTrackName();
- AP4_String GetTrackLanguage();
-
- protected:
- // members
- AP4_TrakAtom* m_TrakAtom;
- bool m_TrakAtomIsOwned;
- Type m_Type;
- AP4_SampleTable* m_SampleTable;
- bool m_SampleTableIsOwned;
- AP4_UI32 m_MovieTimeScale;
- AP4_UI32 m_MediaTimeScale;
-};
-
-#endif // _AP4_TRAK_H_
+/***************************************************************** +| +| AP4 - Track Objects +| +| 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_TRAK_H_ +#define _AP4_TRAK_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Types.h" +#include "Ap4Array.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class AP4_StblAtom; +class AP4_ByteStream; +class AP4_Sample; +class AP4_DataBuffer; +class AP4_TrakAtom; +class AP4_MoovAtom; +class AP4_SampleDescription; +class AP4_SampleTable; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_UI32 AP4_TRACK_DEFAULT_MOVIE_TIMESCALE = 1000; + +const AP4_UI32 AP4_TRACK_FLAG_ENABLED = 0x0001; +const AP4_UI32 AP4_TRACK_FLAG_IN_MOVIE = 0x0002; +const AP4_UI32 AP4_TRACK_FLAG_IN_PREVIEW = 0x0004; + +/*---------------------------------------------------------------------- +| AP4_Track ++---------------------------------------------------------------------*/ +class AP4_Track { + public: + // types + typedef enum { + TYPE_UNKNOWN = 0, + TYPE_AUDIO = 1, + TYPE_VIDEO = 2, + TYPE_SYSTEM = 3, + TYPE_HINT = 4, + TYPE_TEXT = 5, + TYPE_JPEG = 6, + TYPE_RTP = 7, + // ==> Start patch MPC + TYPE_SUBP = 8 + // <== End patch MPC + } Type; + + // methods + AP4_Track(Type type, + AP4_SampleTable* sample_table, // ownership is transfered to the AP4_Track object + AP4_UI32 track_id, + AP4_UI32 movie_time_scale, // 0 = use default + AP4_UI64 track_duration, // in the movie timescale + AP4_UI32 media_time_scale, + AP4_UI64 media_duration, // in the media timescale + const char* language, + AP4_UI32 width, // in 16.16 fixed point + AP4_UI32 height); // in 16.16 fixed point + AP4_Track(AP4_TrakAtom& atom, + AP4_ByteStream& sample_stream, + AP4_UI32 movie_time_scale); + virtual ~AP4_Track(); + + /** + * Clone a track. This is useful if you want to create a track from + * a non-synthetic track (parsed from a file for example) and + * write it out + */ + AP4_Track* Clone(AP4_Result* result = NULL); + + AP4_UI32 GetFlags(); + AP4_Result SetFlags(AP4_UI32 flags); + AP4_Track::Type GetType() { return m_Type; } + AP4_UI32 GetHandlerType(); + AP4_UI64 GetDuration(); // in the timescale of the movie + AP4_UI32 GetDurationMs(); // in milliseconds + AP4_UI32 GetWidth(); // in 16.16 fixed point + AP4_UI32 GetHeight(); // in 16.16 fixed point + AP4_Cardinal GetSampleCount(); + AP4_Result GetSample(AP4_Ordinal index, AP4_Sample& sample); + AP4_Result ReadSample(AP4_Ordinal index, + AP4_Sample& sample, + AP4_DataBuffer& data); + AP4_Result GetSampleIndexForTimeStampMs(AP4_UI32 ts_ms, + AP4_Ordinal& index); + AP4_Ordinal GetNearestSyncSampleIndex(AP4_Ordinal index, bool before=true); + AP4_SampleDescription* GetSampleDescription(AP4_Ordinal index); + AP4_SampleTable* GetSampleTable() { return m_SampleTable; } + AP4_UI32 GetId(); + AP4_Result SetId(AP4_UI32 track_id); + AP4_TrakAtom* GetTrakAtom() { return m_TrakAtom; } + AP4_Result SetMovieTimeScale(AP4_UI32 time_scale); + AP4_UI32 GetMovieTimeScale() { return m_MovieTimeScale; } + AP4_UI32 GetMediaTimeScale(); + AP4_UI64 GetMediaDuration(); // in the timescale of the media + const AP4_String GetTrackName(); + const AP4_String GetTrackLanguage(); + AP4_Result Attach(AP4_MoovAtom* moov); + + protected: + // members + AP4_TrakAtom* m_TrakAtom; + bool m_TrakAtomIsOwned; + Type m_Type; + AP4_SampleTable* m_SampleTable; + bool m_SampleTableIsOwned; + AP4_UI32 m_MovieTimeScale; +}; + +#endif // _AP4_TRAK_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrakAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrakAtom.cpp index 15bd28412..57202f92e 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrakAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrakAtom.cpp @@ -1,204 +1,382 @@ -/*****************************************************************
-|
-| AP4 - trak Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4TrakAtom.h"
-#include "Ap4MdhdAtom.h"
-#include "Ap4VmhdAtom.h"
-#include "Ap4SmhdAtom.h"
-#include "Ap4HmhdAtom.h"
-#include "Ap4NmhdAtom.h"
-#include "Ap4DrefAtom.h"
-#include "Ap4UrlAtom.h"
-#include "Ap4StcoAtom.h"
-#include "Ap4Co64Atom.h"
-#include "Ap4AtomFactory.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_TrakAtom::AP4_TrakAtom
-+---------------------------------------------------------------------*/
-AP4_TrakAtom::AP4_TrakAtom(AP4_SampleTable* sample_table,
- AP4_Atom::Type hdlr_type,
- const char* hdlr_name,
- AP4_UI32 track_id,
- AP4_UI64 creation_time,
- AP4_UI64 modification_time,
- AP4_UI64 track_duration,
- AP4_UI32 media_time_scale,
- AP4_UI64 media_duration,
- AP4_UI16 volume,
- const char* language,
- AP4_UI32 width,
- AP4_UI32 height) :
- AP4_ContainerAtom(AP4_ATOM_TYPE_TRAK)
-{
- AP4_Result result;
-
- // create a tkhd atom
- m_TkhdAtom = DNew AP4_TkhdAtom(creation_time,
- modification_time,
- track_id,
- track_duration,
- volume,
- width,
- height);
-
- // create an edts
-
- // create a mdia atom
- AP4_ContainerAtom* mdia = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_MDIA);
-
- // create a hdlr atom for the mdia atom
- m_HdlrAtom = DNew AP4_HdlrAtom(hdlr_type, hdlr_name);
-
- // create a minf atom
- AP4_ContainerAtom* minf = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_MINF);
-
- // create a media header atom for minf (vmhd, smhd, hmhd or nmhd)
- AP4_Atom* minf_header;
- switch (hdlr_type) {
- case AP4_HANDLER_TYPE_VIDE:
- minf_header = DNew AP4_VmhdAtom(0, 0, 0, 0);
- break;
-
- case AP4_HANDLER_TYPE_SOUN:
- minf_header = DNew AP4_SmhdAtom(0);
- break;
-
- default:
- minf_header = DNew AP4_NmhdAtom();
- break;
- }
-
- // create a dinf atom for minf
- AP4_ContainerAtom* dinf = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_DINF);
-
- // create a url atom as a ref for dref
- AP4_Atom* url = DNew AP4_UrlAtom(); // local ref
-
- // create a dref atom for dinf
- AP4_DrefAtom* dref = DNew AP4_DrefAtom(&url, 1);
-
- // create a stbl atom for minf
- AP4_ContainerAtom* stbl;
- result = sample_table->GenerateStblAtom(stbl);
- if (AP4_FAILED(result)) stbl = NULL;
-
- // populate the dinf atom
- dinf->AddChild(dref);
-
- // populate the minf atom
- minf->AddChild(minf_header);
- minf->AddChild(dinf);
- if (stbl) minf->AddChild(stbl);
-
- // create a mdhd atom for the mdia atom
- AP4_MdhdAtom* mdhd = DNew AP4_MdhdAtom(creation_time,
- modification_time,
- media_time_scale,
- media_duration,
- language);
-
- // populate the mdia atom
- mdia->AddChild(mdhd);
- mdia->AddChild(m_HdlrAtom);
- mdia->AddChild(minf);
-
- // attach the children
- AddChild(m_TkhdAtom);
- AddChild(mdia);
-}
-
-/*----------------------------------------------------------------------
-| AP4_TrakAtom::AP4_TrakAtom
-+---------------------------------------------------------------------*/
-AP4_TrakAtom::AP4_TrakAtom(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory) :
- AP4_ContainerAtom(AP4_ATOM_TYPE_TRAK, size, false, stream, atom_factory),
- m_HdlrAtom(NULL),
- m_TkhdAtom(NULL)
-{
- AP4_Atom* tkhd = FindChild("tkhd");
- if (tkhd != NULL) {
- m_TkhdAtom = dynamic_cast<AP4_TkhdAtom*>(tkhd);
- } else {
- m_TkhdAtom = NULL;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_TrakAtom::GetDuration
-+---------------------------------------------------------------------*/
-AP4_UI64
-AP4_TrakAtom::GetDuration()
-{
- if (m_TkhdAtom) {
- return m_TkhdAtom->GetDuration();
- } else {
- return 0;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_TrakAtom::SetDuration
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_TrakAtom::SetDuration(AP4_UI64 duration)
-{
- if (m_TkhdAtom) {
- return m_TkhdAtom->SetDuration(duration);
- } else {
- return AP4_FAILURE;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_TrakAtom::AdjustChunkOffsets
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_TrakAtom::AdjustChunkOffsets(AP4_Offset offset)
-{
- if (AP4_Atom* atom = FindChild("mdia/minf/stbl/co64")) {
- AP4_Co64Atom* co64 = dynamic_cast<AP4_Co64Atom*>(atom);
- co64->AdjustChunkOffsets(offset);
- }
-
- AP4_Atom* atom = FindChild("mdia/minf/stbl/stco");
- if (atom != NULL) {
- AP4_StcoAtom* stco = dynamic_cast<AP4_StcoAtom*>(atom);
- stco->AdjustChunkOffsets(offset);
- return AP4_SUCCESS;
- } else {
- return AP4_FAILURE;
- }
-}
+/***************************************************************** +| +| AP4 - trak 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 "Ap4TrakAtom.h" +#include "Ap4MdhdAtom.h" +#include "Ap4TkhdAtom.h" +#include "Ap4HdlrAtom.h" +#include "Ap4VmhdAtom.h" +#include "Ap4SmhdAtom.h" +#include "Ap4HmhdAtom.h" +#include "Ap4NmhdAtom.h" +#include "Ap4DrefAtom.h" +#include "Ap4UrlAtom.h" +#include "Ap4StcoAtom.h" +#include "Ap4Co64Atom.h" +#include "Ap4AtomFactory.h" +#include "Ap4SampleTable.h" +#include "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_TrakAtom) + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::AP4_TrakAtom ++---------------------------------------------------------------------*/ +AP4_TrakAtom::AP4_TrakAtom(AP4_SampleTable* sample_table, + AP4_Atom::Type hdlr_type, + const char* hdlr_name, + AP4_UI32 track_id, + AP4_UI32 creation_time, + AP4_UI32 modification_time, + AP4_UI64 track_duration, + AP4_UI32 media_time_scale, + AP4_UI64 media_duration, + AP4_UI16 volume, + const char* language, + AP4_UI32 width, + AP4_UI32 height) : + AP4_ContainerAtom(AP4_ATOM_TYPE_TRAK) +{ + AP4_Result result; + + // create a tkhd atom + m_TkhdAtom = new AP4_TkhdAtom(creation_time, + modification_time, + track_id, + track_duration, + volume, + width, + height); + + // create an edts + + // create a mdia atom + AP4_ContainerAtom* mdia = new AP4_ContainerAtom(AP4_ATOM_TYPE_MDIA); + + // create a hdlr atom for the mdia atom + AP4_HdlrAtom* hdlr = new AP4_HdlrAtom(hdlr_type, hdlr_name); + + // create a minf atom + AP4_ContainerAtom* minf = new AP4_ContainerAtom(AP4_ATOM_TYPE_MINF); + + // create a media header atom for minf (vmhd, smhd, hmhd or nmhd) + AP4_Atom* minf_header; + switch (hdlr_type) { + case AP4_HANDLER_TYPE_VIDE: + minf_header = new AP4_VmhdAtom(0, 0, 0, 0); + break; + + case AP4_HANDLER_TYPE_SOUN: + minf_header = new AP4_SmhdAtom(0); + break; + + default: + minf_header = new AP4_NmhdAtom(); + break; + } + + // create a dinf atom for minf + AP4_ContainerAtom* dinf = new AP4_ContainerAtom(AP4_ATOM_TYPE_DINF); + + // create a url atom as a ref for dref + AP4_Atom* url = new AP4_UrlAtom(); // local ref + + // create a dref atom for dinf + AP4_DrefAtom* dref = new AP4_DrefAtom(&url, 1); + + // create a stbl atom for minf + AP4_ContainerAtom* stbl; + result = sample_table->GenerateStblAtom(stbl); + if (AP4_FAILED(result)) stbl = NULL; + + // populate the dinf atom + dinf->AddChild(dref); + + // populate the minf atom + minf->AddChild(minf_header); + minf->AddChild(dinf); + if (stbl) minf->AddChild(stbl); + + // create a mdhd atom for the mdia atom + m_MdhdAtom = new AP4_MdhdAtom(creation_time, + modification_time, + media_time_scale, + media_duration, + language); + + // populate the mdia atom + mdia->AddChild(m_MdhdAtom); + mdia->AddChild(hdlr); + mdia->AddChild(minf); + + // attach the children + AddChild(m_TkhdAtom); + AddChild(mdia); +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::AP4_TrakAtom ++---------------------------------------------------------------------*/ +AP4_TrakAtom::AP4_TrakAtom(AP4_UI32 size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) : + AP4_ContainerAtom(AP4_ATOM_TYPE_TRAK, size, false, stream, atom_factory) +{ + m_TkhdAtom = AP4_DYNAMIC_CAST(AP4_TkhdAtom, FindChild("tkhd")); + m_MdhdAtom = AP4_DYNAMIC_CAST(AP4_MdhdAtom, FindChild("mdia/mdhd")); +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::GetId ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_TrakAtom::GetId() +{ + return m_TkhdAtom?m_TkhdAtom->GetTrackId():0; +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::SetId ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrakAtom::SetId(AP4_UI32 id) +{ + if (m_TkhdAtom) { + m_TkhdAtom->SetTrackId(id); + return AP4_SUCCESS; + } else { + return AP4_ERROR_INVALID_STATE; + } +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::GetMediaTimeScale ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_TrakAtom::GetMediaTimeScale() +{ + return m_MdhdAtom?m_MdhdAtom->GetTimeScale():0; +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::SetMediaTimeScale ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrakAtom::SetMediaTimeScale(AP4_UI32 timescale) +{ + if (m_MdhdAtom) { + m_MdhdAtom->SetTimeScale(timescale); + return AP4_SUCCESS; + } else { + return AP4_ERROR_INVALID_STATE; + } +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::GetDuration ++---------------------------------------------------------------------*/ +AP4_UI64 +AP4_TrakAtom::GetDuration() +{ + return m_TkhdAtom?m_TkhdAtom->GetDuration():0; +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::SetDuration ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrakAtom::SetDuration(AP4_UI64 duration) +{ + if (m_TkhdAtom) { + m_TkhdAtom->SetDuration(duration); + return AP4_SUCCESS; + } else { + return AP4_ERROR_INVALID_STATE; + } +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::GetMediaDuration ++---------------------------------------------------------------------*/ +AP4_UI64 +AP4_TrakAtom::GetMediaDuration() +{ + return m_MdhdAtom?m_MdhdAtom->GetDuration():0; +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::SetMediaDuration ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrakAtom::SetMediaDuration(AP4_UI32 duration) +{ + if (m_MdhdAtom) { + m_MdhdAtom->SetDuration(duration); + return AP4_SUCCESS; + } else { + return AP4_ERROR_INVALID_STATE; + } +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::GetWidth ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_TrakAtom::GetWidth() +{ + return m_TkhdAtom?m_TkhdAtom->GetWidth():0; +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::SetWidth ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrakAtom::SetWidth(AP4_UI32 width) +{ + if (m_TkhdAtom) { + m_TkhdAtom->SetWidth(width); + return AP4_SUCCESS; + } else { + return AP4_ERROR_INVALID_STATE; + } +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::GetHeight ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_TrakAtom::GetHeight() +{ + return m_TkhdAtom?m_TkhdAtom->GetHeight():0; +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::SetHeight ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrakAtom::SetHeight(AP4_UI32 height) +{ + if (m_TkhdAtom) { + m_TkhdAtom->SetHeight(height); + return AP4_SUCCESS; + } else { + return AP4_ERROR_INVALID_STATE; + } +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::AdjustChunkOffsets ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrakAtom::AdjustChunkOffsets(AP4_SI64 delta) +{ + AP4_Atom* atom; + if ((atom = FindChild("mdia/minf/stbl/stco"))) { + AP4_StcoAtom* stco = AP4_DYNAMIC_CAST(AP4_StcoAtom, atom); + return stco->AdjustChunkOffsets((int)delta); + } else if ((atom = FindChild("mdia/minf/stbl/co64"))) { + AP4_Co64Atom* co64 = AP4_DYNAMIC_CAST(AP4_Co64Atom, atom); + return co64->AdjustChunkOffsets(delta); + } else { + return AP4_ERROR_INVALID_STATE; + } +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::GetChunkOffsets ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrakAtom::GetChunkOffsets(AP4_Array<AP4_UI64>& chunk_offsets) +{ + AP4_Atom* atom; + if ((atom = FindChild("mdia/minf/stbl/stco"))) { + AP4_StcoAtom* stco = AP4_DYNAMIC_CAST(AP4_StcoAtom, atom); + if (stco == NULL) return AP4_ERROR_INTERNAL; + AP4_Cardinal stco_chunk_count = stco->GetChunkCount(); + const AP4_UI32* stco_chunk_offsets = stco->GetChunkOffsets(); + chunk_offsets.SetItemCount(stco_chunk_count); + for (unsigned int i=0; i<stco_chunk_count; i++) { + chunk_offsets[i] = stco_chunk_offsets[i]; + } + return AP4_SUCCESS; + } else if ((atom = FindChild("mdia/minf/stbl/co64"))) { + AP4_Co64Atom* co64 = AP4_DYNAMIC_CAST(AP4_Co64Atom, atom); + if (co64 == NULL) return AP4_ERROR_INTERNAL; + AP4_Cardinal co64_chunk_count = co64->GetChunkCount(); + const AP4_UI64* co64_chunk_offsets = co64->GetChunkOffsets(); + chunk_offsets.SetItemCount(co64_chunk_count); + for (unsigned int i=0; i<co64_chunk_count; i++) { + chunk_offsets[i] = co64_chunk_offsets[i]; + } + return AP4_SUCCESS; + } else { + return AP4_ERROR_INVALID_STATE; + } +} + +/*---------------------------------------------------------------------- +| AP4_TrakAtom::SetChunkOffsets ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrakAtom::SetChunkOffsets(const AP4_Array<AP4_UI64>& chunk_offsets) +{ + AP4_Atom* atom; + if ((atom = FindChild("mdia/minf/stbl/stco"))) { + AP4_StcoAtom* stco = AP4_DYNAMIC_CAST(AP4_StcoAtom, atom); + if (stco == NULL) return AP4_ERROR_INTERNAL; + AP4_Cardinal stco_chunk_count = stco->GetChunkCount(); + AP4_UI32* stco_chunk_offsets = stco->GetChunkOffsets(); + if (stco_chunk_count > chunk_offsets.ItemCount()) { + return AP4_ERROR_OUT_OF_RANGE; + } + for (unsigned int i=0; i<stco_chunk_count; i++) { + stco_chunk_offsets[i] = (AP4_UI32)chunk_offsets[i]; + } + return AP4_SUCCESS; + } else if ((atom = FindChild("mdia/minf/stbl/co64"))) { + AP4_Co64Atom* co64 = AP4_DYNAMIC_CAST(AP4_Co64Atom, atom); + if (co64 == NULL) return AP4_ERROR_INTERNAL; + AP4_Cardinal co64_chunk_count = co64->GetChunkCount(); + AP4_UI64* co64_chunk_offsets = co64->GetChunkOffsets(); + if (co64_chunk_count > chunk_offsets.ItemCount()) { + return AP4_ERROR_OUT_OF_RANGE; + } + for (unsigned int i=0; i<co64_chunk_count; i++) { + co64_chunk_offsets[i] = chunk_offsets[i]; + } + return AP4_SUCCESS; + } else { + return AP4_ERROR_INVALID_STATE; + } +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrakAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrakAtom.h index 6eaaaa6e2..8006375ee 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrakAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrakAtom.h @@ -1,85 +1,103 @@ -/*****************************************************************
-|
-| AP4 - trak Atoms
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_TRAK_ATOM_H_
-#define _AP4_TRAK_ATOM_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4ByteStream.h"
-#include "Ap4List.h"
-#include "Ap4Atom.h"
-#include "Ap4HdlrAtom.h"
-#include "Ap4TkhdAtom.h"
-#include "Ap4ContainerAtom.h"
-#include "Ap4SampleTable.h"
-
-/*----------------------------------------------------------------------
-| AP4_TrakAtom
-+---------------------------------------------------------------------*/
-class AP4_TrakAtom : public AP4_ContainerAtom
-{
- public:
- // methods
- AP4_TrakAtom(AP4_SampleTable* sample_table,
- AP4_Atom::Type hdlr_type,
- const char* hdlr_name,
- AP4_UI32 track_id,
- AP4_UI64 creation_time,
- AP4_UI64 modification_time,
- AP4_UI64 track_duration,
- AP4_UI32 media_time_scale,
- AP4_UI64 media_duration,
- AP4_UI16 volume,
- const char* language,
- AP4_UI32 width,
- AP4_UI32 heigh);
- AP4_TrakAtom(AP4_Size size,
- AP4_ByteStream& stream,
- AP4_AtomFactory& atom_factory);
- AP4_Result AdjustChunkOffsets(AP4_Offset offset);
- AP4_UI32 GetId() {
- return m_TkhdAtom->GetTrackId();
- }
- AP4_Result SetId(AP4_UI32 track_id) {
- return m_TkhdAtom->SetTrackId(track_id);
- }
- AP4_UI64 GetDuration();
- AP4_Result SetDuration(AP4_UI64 duration);
- AP4_TkhdAtom* GetTkhdAtom() { return m_TkhdAtom; }
- AP4_HdlrAtom* GetHdlrAtom() { return m_HdlrAtom; }
-
- private:
- // members
- AP4_HdlrAtom* m_HdlrAtom;
- AP4_TkhdAtom* m_TkhdAtom;
-};
-
-#endif // _AP4_TRAK_ATOM_H_
+/***************************************************************** +| +| AP4 - trak 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_TRAK_ATOM_H_ +#define _AP4_TRAK_ATOM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4ContainerAtom.h" +#include "Ap4Array.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_HdlrAtom; +class AP4_TkhdAtom; +class AP4_MdhdAtom; +class AP4_SampleTable; + +/*---------------------------------------------------------------------- +| AP4_TrakAtom ++---------------------------------------------------------------------*/ +class AP4_TrakAtom : public AP4_ContainerAtom +{ + public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_TrakAtom, AP4_ContainerAtom) + + // class methods + static AP4_TrakAtom* Create(AP4_Size size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory) { + return new AP4_TrakAtom(size, stream, atom_factory); + } + + // methods + AP4_TrakAtom(AP4_SampleTable* sample_table, + AP4_Atom::Type hdlr_type, + const char* hdlr_name, + AP4_UI32 track_id, + AP4_UI32 creation_time, + AP4_UI32 modification_time, + AP4_UI64 track_duration, + AP4_UI32 media_time_scale, + AP4_UI64 media_duration, + AP4_UI16 volume, + const char* language, + AP4_UI32 width, + AP4_UI32 heigh); + AP4_TkhdAtom* GetTkhdAtom() { return m_TkhdAtom; } + AP4_Result AdjustChunkOffsets(AP4_SI64 delta); + AP4_Result GetChunkOffsets(AP4_Array<AP4_UI64>& chunk_offsets); + AP4_Result SetChunkOffsets(const AP4_Array<AP4_UI64>& chunk_offsets); + AP4_UI32 GetId(); + AP4_Result SetId(AP4_UI32 track_id); + AP4_UI64 GetDuration(); + AP4_Result SetDuration(AP4_UI64 duration); + AP4_UI64 GetMediaDuration(); + AP4_Result SetMediaDuration(AP4_UI32 duration); + AP4_UI32 GetMediaTimeScale(); + AP4_Result SetMediaTimeScale(AP4_UI32 timescale); + AP4_UI32 GetWidth(); + AP4_Result SetWidth(AP4_UI32 width); + AP4_UI32 GetHeight(); + AP4_Result SetHeight(AP4_UI32 height); + + private: + // methods + AP4_TrakAtom(AP4_UI32 size, + AP4_ByteStream& stream, + AP4_AtomFactory& atom_factory); + + // members + AP4_TkhdAtom* m_TkhdAtom; + AP4_MdhdAtom* m_MdhdAtom; +}; + +#endif // _AP4_TRAK_ATOM_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrefTypeAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrefTypeAtom.cpp index 504d08e34..bac78fd4c 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrefTypeAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrefTypeAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - tref type Atoms | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,22 +27,35 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4TrefTypeAtom.h" /*---------------------------------------------------------------------- -| AP4_TrefTypeAtom::AP4_TrefTypeAtom +| dynamic cast support +---------------------------------------------------------------------*/ -AP4_TrefTypeAtom::AP4_TrefTypeAtom(AP4_Atom::Type type, - AP4_Size size, +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_TrefTypeAtom) + +/*---------------------------------------------------------------------- +| AP4_TrefTypeAtom::AP4_TrefTypeAtom ++---------------------------------------------------------------------*/ +AP4_TrefTypeAtom::AP4_TrefTypeAtom(AP4_Atom::Type type) : + AP4_Atom(type, AP4_ATOM_HEADER_SIZE) +{ +} + +/*---------------------------------------------------------------------- +| AP4_TrefTypeAtom::AP4_TrefTypeAtom ++---------------------------------------------------------------------*/ +AP4_TrefTypeAtom::AP4_TrefTypeAtom(AP4_Atom::Type type, + AP4_UI32 size, AP4_ByteStream& stream) : - AP4_Atom(type, size, false, stream) + AP4_Atom(type, size) { AP4_Size data_size = size - 8; // size and atom type // read the track ids - while (data_size != 0) { + while (data_size >= 4) { AP4_UI32 track_id; stream.ReadUI32(track_id); m_TrackIds.Append(track_id); @@ -51,7 +64,20 @@ AP4_TrefTypeAtom::AP4_TrefTypeAtom(AP4_Atom::Type type, } /*---------------------------------------------------------------------- -| AP4_TrefTypeAtom::WriteFields +| AP4_TrefTypeAtom::AddTrackId ++---------------------------------------------------------------------*/ +AP4_Result +AP4_TrefTypeAtom::AddTrackId(AP4_UI32 track_id) +{ + AP4_Result result = m_TrackIds.Append(track_id); + if (AP4_SUCCEEDED(result)) { + m_Size32 += 4; + } + return result; +} + +/*---------------------------------------------------------------------- +| AP4_TrefTypeAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_TrefTypeAtom::WriteFields(AP4_ByteStream& stream) @@ -68,7 +94,7 @@ AP4_TrefTypeAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_TrefTypeAtom::InspectFields +| AP4_TrefTypeAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_TrefTypeAtom::InspectFields(AP4_AtomInspector& inspector) diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrefTypeAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrefTypeAtom.h index 2c2f1412a..438f03f53 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrefTypeAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4TrefTypeAtom.h @@ -2,7 +2,7 @@ | | AP4 - tref type Atoms | -| Copyright 2002-2005 Gilles Boccon-Gibod & Julien Boeuf +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,26 +30,41 @@ #define _AP4_TREF_TYPE_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4Atom.h" #include "Ap4Array.h" /*---------------------------------------------------------------------- -| AP4_TrefTypeAtom +| AP4_TrefTypeAtom +---------------------------------------------------------------------*/ class AP4_TrefTypeAtom : public AP4_Atom { public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_TrefTypeAtom, AP4_Atom) + + // class methods + static AP4_TrefTypeAtom* Create(AP4_Atom::Type type, + AP4_UI32 size, + AP4_ByteStream& stream) { + return new AP4_TrefTypeAtom(type, size, stream); + } + + // contructor + AP4_TrefTypeAtom(AP4_Atom::Type type); + // methods - AP4_TrefTypeAtom(AP4_Atom::Type type, AP4_Size size, AP4_ByteStream& stream); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); - + AP4_Result AddTrackId(AP4_UI32 track_id); + // accessors const AP4_Array<AP4_UI32>& GetTrackIds() { return m_TrackIds; } +private: + // methods + AP4_TrefTypeAtom(AP4_Atom::Type type, AP4_UI32 size, AP4_ByteStream& stream); + // members AP4_Array<AP4_UI32> m_TrackIds; }; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Types.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Types.h index 38a471069..86409c337 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Types.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Types.h @@ -1,67 +1,76 @@ -/*****************************************************************
-|
-| AP4 - Shared Types
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_TYPES_H_
-#define _AP4_TYPES_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4Config.h"
-#if defined(AP4_CONFIG_HAVE_CPP_STRING_H)
-#include <string>
-#endif
-
-/*----------------------------------------------------------------------
-| types
-+---------------------------------------------------------------------*/
-typedef int AP4_Result;
-typedef unsigned long AP4_Flags;
-typedef unsigned long AP4_Mask;
-typedef unsigned long AP4_Size;
-typedef unsigned long AP4_Offset;
-typedef unsigned long AP4_Range;
-typedef unsigned long AP4_Cardinal;
-typedef unsigned long AP4_Ordinal;
-// typedef unsigned long AP4_TimeStamp;
-// typedef unsigned long AP4_Duration;
-typedef int AP4_Coordinate;
-typedef int AP4_Distance;
-typedef int AP4_Integer;
-typedef unsigned int AP4_UI32;
-typedef unsigned short AP4_UI16;
-typedef unsigned char AP4_UI08;
-typedef float AP4_Float;
-typedef std::string AP4_String;
-typedef unsigned char AP4_Byte;
-
-typedef unsigned long long AP4_TimeStamp;
-typedef unsigned long long AP4_Duration;
-typedef unsigned long long AP4_UI64;
-
-#endif // _AP4_TYPES_H_
+/***************************************************************** +| +| AP4 - Shared Types +| +| 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_TYPES_H_ +#define _AP4_TYPES_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Config.h" + +/*---------------------------------------------------------------------- +| types ++---------------------------------------------------------------------*/ +typedef int AP4_Result; +typedef unsigned int AP4_Flags; +typedef unsigned int AP4_Mask; +typedef unsigned int AP4_Cardinal; +typedef unsigned int AP4_Ordinal; +typedef unsigned int AP4_UI32; +typedef signed int AP4_SI32; +typedef unsigned short AP4_UI16; +typedef signed short AP4_SI16; +typedef unsigned char AP4_UI08; +typedef unsigned char AP4_Byte; +typedef unsigned long AP4_Size; + +// the rest depends on whether the platform supports 64-bit integers +#if defined(AP4_CONFIG_HAVE_INT64) + // we have 64-bit integers + typedef AP4_CONFIG_INT64_TYPE AP4_SI64; + typedef unsigned AP4_CONFIG_INT64_TYPE AP4_UI64; + typedef unsigned AP4_CONFIG_INT64_TYPE AP4_LargeSize; + typedef AP4_CONFIG_INT64_TYPE AP4_Offset; + typedef unsigned AP4_CONFIG_INT64_TYPE AP4_Position; +#else + // use only 32-bit integers + typedef struct { + AP4_UI32 hi; + AP4_UI32 lo; + } AP4_UI64, AP4_SI64; + typedef unsigned long AP4_LargeSize; + typedef long AP4_Offset; + typedef unsigned long AP4_Position; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#endif // _AP4_TYPES_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UrlAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UrlAtom.cpp index b40be3504..8659d9837 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UrlAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UrlAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - url Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,33 +27,47 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4UrlAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_UrlAtom::AP4_UrlAtom +| AP4_UrlAtom::Create ++---------------------------------------------------------------------*/ +AP4_UrlAtom* +AP4_UrlAtom::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_UrlAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_UrlAtom::AP4_UrlAtom +---------------------------------------------------------------------*/ AP4_UrlAtom::AP4_UrlAtom() : - AP4_Atom(AP4_ATOM_TYPE_URL, AP4_FULL_ATOM_HEADER_SIZE, true) + AP4_Atom(AP4_ATOM_TYPE_URL, AP4_FULL_ATOM_HEADER_SIZE, 0, 1) { - m_Flags = 1; // local ref } /*---------------------------------------------------------------------- -| AP4_UrlAtom::AP4_UrlAtom +| AP4_UrlAtom::AP4_UrlAtom +---------------------------------------------------------------------*/ -AP4_UrlAtom::AP4_UrlAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_URL, size, true, stream) +AP4_UrlAtom::AP4_UrlAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_URL, size, version, flags) { if ((m_Flags & 1) == 0) { // not self contained AP4_Size str_size = size-AP4_FULL_ATOM_HEADER_SIZE; if (str_size > 0) { - char* str = DNew char[str_size]; + char* str = new char[str_size]; stream.Read(str, str_size); str[str_size-1] = '\0'; // force null-termination m_Url = str; @@ -63,7 +77,7 @@ AP4_UrlAtom::AP4_UrlAtom(AP4_Size size, AP4_ByteStream& stream) : } /*---------------------------------------------------------------------- -| AP4_UrlAtom::WriteFields +| AP4_UrlAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_UrlAtom::WriteFields(AP4_ByteStream& stream) @@ -73,18 +87,20 @@ AP4_UrlAtom::WriteFields(AP4_ByteStream& stream) return AP4_SUCCESS; } else { // url (not self contained) - AP4_Result result = stream.Write(m_Url.c_str(), m_Url.length()+1); - if (AP4_FAILED(result)) return result; + if (m_Size32 > AP4_FULL_ATOM_HEADER_SIZE) { + AP4_Result result = stream.Write(m_Url.GetChars(), m_Url.GetLength()+1); + if (AP4_FAILED(result)) return result; - // pad with zeros if necessary - AP4_Size padding = m_Size-(AP4_FULL_ATOM_HEADER_SIZE+m_Url.length()+1); - while (padding--) stream.WriteUI08(0); + // pad with zeros if necessary + AP4_Size padding = m_Size32-(AP4_FULL_ATOM_HEADER_SIZE+m_Url.GetLength()+1); + while (padding--) stream.WriteUI08(0); + } return AP4_SUCCESS; } } /*---------------------------------------------------------------------- -| AP4_UrlAtom::InspectFields +| AP4_UrlAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_UrlAtom::InspectFields(AP4_AtomInspector& inspector) @@ -92,7 +108,7 @@ AP4_UrlAtom::InspectFields(AP4_AtomInspector& inspector) if (m_Flags & 1) { inspector.AddField("location", "[local to file]"); } else { - inspector.AddField("location", m_Url.c_str()); + inspector.AddField("location", m_Url.GetChars()); } return AP4_SUCCESS; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UrlAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UrlAtom.h index ee63e365e..3e354f70c 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UrlAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4UrlAtom.h @@ -2,7 +2,7 @@ | | AP4 - url Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,26 +30,32 @@ #define _AP4_URL_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4List.h" #include "Ap4Atom.h" +#include "Ap4String.h" /*---------------------------------------------------------------------- -| AP4_UrlAtom +| AP4_UrlAtom +---------------------------------------------------------------------*/ class AP4_UrlAtom : public AP4_Atom { - public: +public: + // class methods + static AP4_UrlAtom* Create(AP4_Size size, AP4_ByteStream& stream); + // methods AP4_UrlAtom(); // local ref only (no URL string) - AP4_UrlAtom(AP4_Size size, AP4_ByteStream& stream); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); - private: +private: + // methods + AP4_UrlAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + // members AP4_String m_Url; }; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Utils.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Utils.cpp index 29f208d00..94b3975d2 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Utils.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Utils.cpp @@ -1,335 +1,210 @@ -/*****************************************************************
-|
-| AP4 - Utilities
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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 "Ap4.h"
-#include "Ap4Utils.h"
-
-/*----------------------------------------------------------------------
-| AP4_BytesToUInt64BE
-+---------------------------------------------------------------------*/
-unsigned long long
-AP4_BytesToUInt64BE(const unsigned char* bytes)
-{
- return
- ( ((unsigned long long)bytes[0])<<56 ) |
- ( ((unsigned long long)bytes[1])<<48 ) |
- ( ((unsigned long long)bytes[2])<<40 ) |
- ( ((unsigned long long)bytes[3])<<32 ) |
- ( ((unsigned long long)bytes[4])<<24 ) |
- ( ((unsigned long long)bytes[5])<<16 ) |
- ( ((unsigned long long)bytes[6])<<8 ) |
- ( ((unsigned long long)bytes[7]) );
-}
-
-/*----------------------------------------------------------------------
-| AP4_BytesToUInt32BE
-+---------------------------------------------------------------------*/
-unsigned long
-AP4_BytesToUInt32BE(const unsigned char* bytes)
-{
- return
- ( ((unsigned long)bytes[0])<<24 ) |
- ( ((unsigned long)bytes[1])<<16 ) |
- ( ((unsigned long)bytes[2])<<8 ) |
- ( ((unsigned long)bytes[3]) );
-}
-
-/*----------------------------------------------------------------------
-| AP4_BytesToUInt24BE
-+---------------------------------------------------------------------*/
-unsigned long
-AP4_BytesToUInt24BE(const unsigned char* bytes)
-{
- return
- ( ((unsigned long)bytes[0])<<16 ) |
- ( ((unsigned long)bytes[1])<<8 ) |
- ( ((unsigned long)bytes[2]) );
-}
-
-/*----------------------------------------------------------------------
-| AP4_BytesToUInt16BE
-+---------------------------------------------------------------------*/
-unsigned short
-AP4_BytesToUInt16BE(const unsigned char* bytes)
-{
- return
- ( ((unsigned short)bytes[0])<<8 ) |
- ( ((unsigned short)bytes[1]) );
-}
-
-/*----------------------------------------------------------------------
-| AP4_BytesFromUInt64BE
-+---------------------------------------------------------------------*/
-void
-AP4_BytesFromUInt64BE(unsigned char* bytes, unsigned long long value)
-{
- bytes[0] = (unsigned char)(value >> 56);
- bytes[1] = (unsigned char)(value >> 48);
- bytes[2] = (unsigned char)(value >> 40);
- bytes[3] = (unsigned char)(value >> 32);
- bytes[4] = (unsigned char)(value >> 24);
- bytes[5] = (unsigned char)(value >> 16);
- bytes[6] = (unsigned char)(value >> 8);
- bytes[7] = (unsigned char)(value );
-}
-
-/*----------------------------------------------------------------------
-| AP4_BytesFromUInt32BE
-+---------------------------------------------------------------------*/
-void
-AP4_BytesFromUInt32BE(unsigned char* bytes, unsigned long value)
-{
- bytes[0] = (unsigned char)(value >> 24);
- bytes[1] = (unsigned char)(value >> 16);
- bytes[2] = (unsigned char)(value >> 8);
- bytes[3] = (unsigned char)(value );
-}
-
-/*----------------------------------------------------------------------
-| AP4_BytesFromUInt24BE
-+---------------------------------------------------------------------*/
-void
-AP4_BytesFromUInt24BE(unsigned char* bytes, unsigned long value)
-{
- bytes[0] = (unsigned char)(value >> 16);
- bytes[1] = (unsigned char)(value >> 8);
- bytes[2] = (unsigned char)(value );
-}
-
-/*----------------------------------------------------------------------
-| AP4_BytesFromUInt16BE
-+---------------------------------------------------------------------*/
-void
-AP4_BytesFromUInt16BE(unsigned char* bytes, unsigned short value)
-{
- bytes[0] = (unsigned char)(value >> 8);
- bytes[1] = (unsigned char)(value );
-}
-
-/*----------------------------------------------------------------------
-| AP4_MakePrefixString
-+---------------------------------------------------------------------*/
-static void
-AP4_MakePrefixString(AP4_Offset indent, char* prefix, AP4_Size size)
-{
- if (size == 0) return;
- if (indent >= size-1) indent = size-1;
- for (unsigned int i=0; i<indent; i++) {
- prefix[i] = ' ';
- }
- prefix[indent] = '\0';
-}
-
-/*----------------------------------------------------------------------
-| AP4_DurationMsFromUnits
-+---------------------------------------------------------------------*/
-unsigned long
-AP4_DurationMsFromUnits(AP4_UI64 units, unsigned long units_per_second)
-{
- if (units_per_second == 0) return 0;
- return (unsigned long)(((float)units*1000.0f)/(float)units_per_second);
-}
-
-/*----------------------------------------------------------------------
-| AP4_ConvertTime
-+---------------------------------------------------------------------*/
-AP4_UI64
-AP4_ConvertTime(AP4_UI64 time_value,
- unsigned long from_time_scale,
- unsigned long to_time_scale)
-{
- if (from_time_scale == 0) return 0;
- float ratio = (float)to_time_scale/(float)from_time_scale;
- return ((AP4_UI64)((float)time_value*ratio));
-}
-
-/*----------------------------------------------------------------------
-| AP4_FormatFourChars
-+---------------------------------------------------------------------*/
-void
-AP4_FormatFourChars(char* str, AP4_UI32 value) {
- str[0] = (value >> 24) & 0xFF;
- str[1] = (value >> 16) & 0xFF;
- str[2] = (value >> 8) & 0xFF;
- str[3] = (value ) & 0xFF;
- str[4] = '\0';
-}
-
-/*----------------------------------------------------------------------
-| AP4_SplitArgs
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SplitArgs(char* arg, char*& arg0, char*& arg1)
-{
- arg0 = arg;
- char* c = arg;
- while (*c != 0 && *c != ':') {
- c++;
- }
- if (*c == ':') {
- *c++ = '\0';
- arg1 = c;
- return AP4_SUCCESS;
- } else {
- return AP4_FAILURE;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_SplitArgs
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_SplitArgs(char* arg, char*& arg0, char*& arg1, char*& arg2)
-{
- AP4_Result result = AP4_SplitArgs(arg, arg0, arg1);
- if (AP4_FAILED(result)) return result;
- return AP4_SplitArgs(arg1, arg1, arg2);
-}
-
-/*----------------------------------------------------------------------
-| AP4_HexNibble
-+---------------------------------------------------------------------*/
-static unsigned char
-AP4_HexNibble(char c)
-{
- switch (c) {
- case '0': return 0;
- case '1': return 1;
- case '2': return 2;
- case '3': return 3;
- case '4': return 4;
- case '5': return 5;
- case '6': return 6;
- case '7': return 7;
- case '8': return 8;
- case '9': return 9;
- case 'a': case 'A': return 10;
- case 'b': case 'B': return 11;
- case 'c': case 'C': return 12;
- case 'd': case 'D': return 13;
- case 'e': case 'E': return 14;
- case 'f': case 'F': return 15;
- default: return 0;
- }
-}
-
-/*----------------------------------------------------------------------
-| AP4_ParseHex
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_ParseHex(const char* hex, unsigned char* bytes, unsigned int count)
-{
- if (strlen(hex) != 2*count) return AP4_ERROR_INVALID_PARAMETERS;
- for (unsigned int i=0; i<count; i++) {
- bytes[i] = (AP4_HexNibble(hex[2*i]) << 4) | (AP4_HexNibble(hex[2*i+1]));
- }
- return AP4_SUCCESS;
-}
-
-/*----------------------------------------------------------------------
-| AP4_PrintInspector::AP4_PrintInspector
-+---------------------------------------------------------------------*/
-AP4_PrintInspector::AP4_PrintInspector(AP4_ByteStream& stream) :
- m_Stream(&stream),
- m_Indent(0)
-{
- m_Stream->AddReference();
-}
-
-/*----------------------------------------------------------------------
-| AP4_PrintInspector::~AP4_PrintInspector
-+---------------------------------------------------------------------*/
-AP4_PrintInspector::~AP4_PrintInspector()
-{
- m_Stream->Release();
-}
-
-/*----------------------------------------------------------------------
-| AP4_PrintInspector::StartElement
-+---------------------------------------------------------------------*/
-void
-AP4_PrintInspector::StartElement(const char* name, const char* info)
-{
- char prefix[256];
- AP4_MakePrefixString(m_Indent, prefix, sizeof(prefix));
- m_Stream->WriteString(prefix);
- m_Stream->WriteString(name);
- if (info) {
- m_Stream->Write(" ", 1);
- m_Stream->WriteString(info);
- }
- m_Stream->Write("\n", 1);
-
- m_Indent += 2;
-}
-
-/*----------------------------------------------------------------------
-| AP4_PrintInspector::EndElement
-+---------------------------------------------------------------------*/
-void
-AP4_PrintInspector::EndElement()
-{
- m_Indent -= 2;
-}
-
-/*----------------------------------------------------------------------
-| AP4_PrintInspector::AddField
-+---------------------------------------------------------------------*/
-void
-AP4_PrintInspector::AddField(const char* name, const char* value, FormatHint hint)
-{
- char prefix[256];
- AP4_MakePrefixString(m_Indent, prefix, sizeof(prefix));
- m_Stream->WriteString(prefix);
-
- m_Stream->WriteString(name);
- m_Stream->WriteString(" = ");
- m_Stream->WriteString(value);
- m_Stream->Write("\n", 1);
-}
-
-/*----------------------------------------------------------------------
-| AP4_PrintInspector::AddField
-+---------------------------------------------------------------------*/
-void
-AP4_PrintInspector::AddField(const char* name, AP4_UI32 value, FormatHint hint)
-{
- char prefix[256];
- AP4_MakePrefixString(m_Indent, prefix, sizeof(prefix));
- m_Stream->WriteString(prefix);
-
- char str[32];
- AP4_StringFormat(str, sizeof(str), "%d", value);
- m_Stream->WriteString(name);
- m_Stream->WriteString(" = ");
- m_Stream->WriteString(str);
- m_Stream->Write("\n", 1);
-}
+/***************************************************************** +| +| AP4 - Utilities +| +| 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 "Ap4Utils.h" + +/*---------------------------------------------------------------------- +| AP4_BytesToDoubleBE ++---------------------------------------------------------------------*/ +double +AP4_BytesToDoubleBE(const unsigned char* bytes) +{ + AP4_UI64 i_value = AP4_BytesToUInt64BE(bytes); + void* v_value = reinterpret_cast<void*>(&i_value); + double* d_value = reinterpret_cast<double*>(v_value); + + return *d_value; +} + +/*---------------------------------------------------------------------- +| AP4_BytesToUInt64BE ++---------------------------------------------------------------------*/ +AP4_UI64 +AP4_BytesToUInt64BE(const unsigned char* bytes) +{ + return + ( ((AP4_UI64)bytes[0])<<56 ) | + ( ((AP4_UI64)bytes[1])<<48 ) | + ( ((AP4_UI64)bytes[2])<<40 ) | + ( ((AP4_UI64)bytes[3])<<32 ) | + ( ((AP4_UI64)bytes[4])<<24 ) | + ( ((AP4_UI64)bytes[5])<<16 ) | + ( ((AP4_UI64)bytes[6])<<8 ) | + ( ((AP4_UI64)bytes[7]) ); +} + +/*---------------------------------------------------------------------- +| AP4_BytesFromDoubleBE ++---------------------------------------------------------------------*/ +void +AP4_BytesFromDoubleBE(unsigned char* bytes, double value) +{ + void* v_value = reinterpret_cast<void*>(&value); + AP4_UI64* i_value = reinterpret_cast<AP4_UI64*>(v_value); + + AP4_BytesFromUInt64BE(bytes, *i_value); +} + +/*---------------------------------------------------------------------- +| AP4_BytesFromUInt64BE ++---------------------------------------------------------------------*/ +void +AP4_BytesFromUInt64BE(unsigned char* bytes, AP4_UI64 value) +{ + bytes[0] = (unsigned char)(value >> 56); + bytes[1] = (unsigned char)(value >> 48); + bytes[2] = (unsigned char)(value >> 40); + bytes[3] = (unsigned char)(value >> 32); + bytes[4] = (unsigned char)(value >> 24); + bytes[5] = (unsigned char)(value >> 16); + bytes[6] = (unsigned char)(value >> 8); + bytes[7] = (unsigned char)(value ); +} + +/*---------------------------------------------------------------------- +| AP4_DurationMsFromUnits ++---------------------------------------------------------------------*/ +AP4_UI32 +AP4_DurationMsFromUnits(AP4_UI64 units, AP4_UI32 units_per_second) +{ + if (units_per_second == 0) return 0; + return (AP4_UI32)(((double)units*1000.0)/(double)units_per_second); +} + +/*---------------------------------------------------------------------- +| AP4_ConvertTime ++---------------------------------------------------------------------*/ +AP4_UI64 +AP4_ConvertTime(AP4_UI64 time_value, + AP4_UI32 from_time_scale, + AP4_UI32 to_time_scale) +{ + if (from_time_scale == 0) return 0; + double ratio = (double)to_time_scale/(double)from_time_scale; + return ((AP4_UI64)((double)time_value*ratio)); +} + +/*---------------------------------------------------------------------- +| AP4_FormatFourChars ++---------------------------------------------------------------------*/ +void +AP4_FormatFourChars(char* str, AP4_UI32 value) { + str[0] = (value >> 24) & 0xFF; + str[1] = (value >> 16) & 0xFF; + str[2] = (value >> 8) & 0xFF; + str[3] = (value ) & 0xFF; + str[4] = '\0'; +} + +/*---------------------------------------------------------------------- +| AP4_FormatFourCharsPrintable ++---------------------------------------------------------------------*/ +void +AP4_FormatFourCharsPrintable(char* str, AP4_UI32 value) { + AP4_FormatFourChars(str, value); + for (int i=0; i<4; i++) { + if (str[i]<' ' || str[i] >= 127) { + str[i] = '.'; + } + } +} + +/*---------------------------------------------------------------------- +| AP4_SplitArgs ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SplitArgs(char* arg, char*& arg0, char*& arg1) +{ + arg0 = arg; + char* c = arg; + while (*c != 0 && *c != ':') { + c++; + } + if (*c == ':') { + *c++ = '\0'; + arg1 = c; + return AP4_SUCCESS; + } else { + return AP4_FAILURE; + } +} + +/*---------------------------------------------------------------------- +| AP4_SplitArgs ++---------------------------------------------------------------------*/ +AP4_Result +AP4_SplitArgs(char* arg, char*& arg0, char*& arg1, char*& arg2) +{ + AP4_Result result = AP4_SplitArgs(arg, arg0, arg1); + if (AP4_FAILED(result)) return result; + return AP4_SplitArgs(arg1, arg1, arg2); +} + +/*---------------------------------------------------------------------- +| AP4_HexNibble ++---------------------------------------------------------------------*/ +static unsigned char +AP4_HexNibble(char c) +{ + switch (c) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + case 'a': case 'A': return 10; + case 'b': case 'B': return 11; + case 'c': case 'C': return 12; + case 'd': case 'D': return 13; + case 'e': case 'E': return 14; + case 'f': case 'F': return 15; + default: return 0; + } +} + +/*---------------------------------------------------------------------- +| AP4_ParseHex ++---------------------------------------------------------------------*/ +AP4_Result +AP4_ParseHex(const char* hex, unsigned char* bytes, unsigned int count) +{ + if (AP4_StringLength(hex) != 2*count) return AP4_ERROR_INVALID_PARAMETERS; + for (unsigned int i=0; i<count; i++) { + bytes[i] = (AP4_HexNibble(hex[2*i]) << 4) | (AP4_HexNibble(hex[2*i+1])); + } + return AP4_SUCCESS; +} + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Utils.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Utils.h index 9943fe18a..2b3dd6895 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Utils.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4Utils.h @@ -1,103 +1,180 @@ -/*****************************************************************
-|
-| AP4 - Utilities
-|
-| Copyright 2002 Gilles Boccon-Gibod
-|
-|
-| 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_UTILS_H_
-#define _AP4_UTILS_H_
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4.h"
-#include "Ap4Config.h"
-#include "Ap4Atom.h"
-
-/*----------------------------------------------------------------------
-| MIN & MAX
-+---------------------------------------------------------------------*/
-#define MIN(a,b) (a<b)?a:b
-#define MAX(a,b) (a>b)?a:b
-
-/*----------------------------------------------------------------------
-| byte I/O
-+---------------------------------------------------------------------*/
-unsigned long long AP4_BytesToUInt64BE(const unsigned char* bytes);
-unsigned long AP4_BytesToUInt32BE(const unsigned char* bytes);
-unsigned long AP4_BytesToUInt24BE(const unsigned char* bytes);
-unsigned short AP4_BytesToUInt16BE(const unsigned char* bytes);
-void AP4_BytesFromUInt64BE(unsigned char* bytes, unsigned long long value);
-void AP4_BytesFromUInt32BE(unsigned char* bytes, unsigned long value);
-void AP4_BytesFromUInt24BE(unsigned char* bytes, unsigned long value);
-void AP4_BytesFromUInt16BE(unsigned char* bytes, unsigned short value);
-unsigned long AP4_DurationMsFromUnits(AP4_UI64 units,
- unsigned long units_per_second);
-AP4_UI64 AP4_ConvertTime(AP4_UI64 time_value,
- unsigned long from_time_scale,
- unsigned long to_time_scale);
-
-/*----------------------------------------------------------------------
-| string utils
-+---------------------------------------------------------------------*/
-#if defined (AP4_CONFIG_HAVE_STDIO_H)
-#include <stdio.h>
-#endif
-
-#if defined (AP4_CONFIG_HAVE_SNPRINTF)
-#define AP4_StringFormat snprintf
-#else
-int AP4_StringFormat(char* str, AP4_Size size, const char* format, ...);
-#endif
-
-void AP4_FormatFourChars(char* str, AP4_UI32 value);
-AP4_Result
-AP4_ParseHex(const char* hex, unsigned char* bytes, unsigned int count);
-AP4_Result
-AP4_SplitArgs(char* arg, char*& arg0, char*& arg1, char*& arg2);
-AP4_Result
-AP4_SplitArgs(char* arg, char*& arg0, char*& arg1);
-
-/*----------------------------------------------------------------------
-| AP4_PrintInspector
-+---------------------------------------------------------------------*/
-class AP4_PrintInspector : public AP4_AtomInspector {
-public:
- AP4_PrintInspector(AP4_ByteStream& stream);
- ~AP4_PrintInspector();
-
- // methods
- void StartElement(const char* name, const char* info);
- void EndElement();
- void AddField(const char* name, AP4_UI32 value, FormatHint hint);
- void AddField(const char* name, const char* value, FormatHint hint);
-
-private:
- // members
- AP4_ByteStream* m_Stream;
- AP4_Cardinal m_Indent;
-};
-
-#endif // _AP4_UTILS_H_
+/***************************************************************** +| +| AP4 - Utilities +| +| 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_UTILS_H_ +#define _AP4_UTILS_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Config.h" +#include "Ap4Types.h" +#include "Ap4Results.h" +#include "Ap4Config.h" + +/*---------------------------------------------------------------------- +| non-inline functions ++---------------------------------------------------------------------*/ +double AP4_BytesToDoubleBE(const unsigned char* bytes); +AP4_UI64 AP4_BytesToUInt64BE(const unsigned char* bytes); +void AP4_BytesFromDoubleBE(unsigned char* bytes, double value); +void AP4_BytesFromUInt64BE(unsigned char* bytes, AP4_UI64 value); + +/*---------------------------------------------------------------------- +| AP4_BytesToUInt32BE ++---------------------------------------------------------------------*/ +inline AP4_UI32 +AP4_BytesToUInt32BE(const unsigned char* bytes) +{ + return + ( ((AP4_UI32)bytes[0])<<24 ) | + ( ((AP4_UI32)bytes[1])<<16 ) | + ( ((AP4_UI32)bytes[2])<<8 ) | + ( ((AP4_UI32)bytes[3]) ); +} + +/*---------------------------------------------------------------------- +| AP4_BytesToInt32BE ++---------------------------------------------------------------------*/ +inline AP4_SI32 +AP4_BytesToInt32BE(const unsigned char* bytes) +{ + return AP4_BytesToUInt32BE(bytes); +} + +/*---------------------------------------------------------------------- +| AP4_BytesToUInt24BE ++---------------------------------------------------------------------*/ +inline AP4_UI32 +AP4_BytesToUInt24BE(const unsigned char* bytes) +{ + return + ( ((AP4_UI32)bytes[0])<<16 ) | + ( ((AP4_UI32)bytes[1])<<8 ) | + ( ((AP4_UI32)bytes[2]) ); +} + +/*---------------------------------------------------------------------- +| AP4_BytesToInt16BE ++---------------------------------------------------------------------*/ +inline AP4_UI16 +AP4_BytesToUInt16BE(const unsigned char* bytes) +{ + return + ( ((AP4_UI16)bytes[0])<<8 ) | + ( ((AP4_UI16)bytes[1]) ); +} + +/*---------------------------------------------------------------------- +| AP4_BytesToInt16BE ++---------------------------------------------------------------------*/ +inline AP4_SI16 +AP4_BytesToInt16BE(const unsigned char* bytes) +{ + return (AP4_SI16)AP4_BytesToUInt16BE(bytes); +} + +/*---------------------------------------------------------------------- +| AP4_BytesFromUInt32BE ++---------------------------------------------------------------------*/ +inline void +AP4_BytesFromUInt32BE(unsigned char* bytes, AP4_UI32 value) +{ + bytes[0] = (unsigned char)(value >> 24); + bytes[1] = (unsigned char)(value >> 16); + bytes[2] = (unsigned char)(value >> 8); + bytes[3] = (unsigned char)(value ); +} + +/*---------------------------------------------------------------------- +| AP4_BytesFromUInt24BE ++---------------------------------------------------------------------*/ +inline void +AP4_BytesFromUInt24BE(unsigned char* bytes, AP4_UI32 value) +{ + bytes[0] = (unsigned char)(value >> 16); + bytes[1] = (unsigned char)(value >> 8); + bytes[2] = (unsigned char)(value ); +} + +/*---------------------------------------------------------------------- +| AP4_BytesFromUInt16BE ++---------------------------------------------------------------------*/ +inline void +AP4_BytesFromUInt16BE(unsigned char* bytes, AP4_UI16 value) +{ + bytes[0] = (unsigned char)(value >> 8); + bytes[1] = (unsigned char)(value ); +} + +/*---------------------------------------------------------------------- +| time functions ++---------------------------------------------------------------------*/ +AP4_UI32 AP4_DurationMsFromUnits(AP4_UI64 units, + AP4_UI32 units_per_second); +AP4_UI64 AP4_ConvertTime(AP4_UI64 time_value, + AP4_UI32 from_time_scale, + AP4_UI32 to_time_scale); + +/*---------------------------------------------------------------------- +| string utils ++---------------------------------------------------------------------*/ +#if defined (AP4_CONFIG_HAVE_STDIO_H) +#include <stdio.h> +#endif + +#if defined (AP4_CONFIG_HAVE_SNPRINTF) +#define AP4_FormatString AP4_snprintf +#else +int AP4_FormatString(char* str, AP4_Size size, const char* format, ...); +#endif +#if defined(AP4_CONFIG_HAVE_VSNPRINTF) +#define AP4_FormatStringVN(s,c,f,a) AP4_vsnprintf(s,c,f,a) +#else +extern int AP4_FormatStringVN(char *buffer, size_t count, const char *format, va_list argptr); +#endif + +#if defined (AP4_CONFIG_HAVE_STRING_H) +#include <string.h> +#define AP4_StringLength(x) strlen(x) +#define AP4_CopyMemory(x,y,z) memcpy(x,y,z) +#define AP4_SetMemory(x,y,z) memset(x,y,z) +#define AP4_CompareStrings(x,y) strcmp(x,y) +#endif + +void AP4_FormatFourChars(char* str, AP4_UI32 value); +void AP4_FormatFourCharsPrintable(char* str, AP4_UI32 value); +AP4_Result +AP4_ParseHex(const char* hex, unsigned char* bytes, unsigned int count); +AP4_Result +AP4_SplitArgs(char* arg, char*& arg0, char*& arg1, char*& arg2); +AP4_Result +AP4_SplitArgs(char* arg, char*& arg0, char*& arg1); + + +#endif // _AP4_UTILS_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4VmhdAtom.cpp b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4VmhdAtom.cpp index fb0a5b032..0aaf37c72 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4VmhdAtom.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4VmhdAtom.cpp @@ -2,7 +2,7 @@ | | AP4 - vmhd Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -27,19 +27,31 @@ ****************************************************************/ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" #include "Ap4VmhdAtom.h" #include "Ap4AtomFactory.h" #include "Ap4Utils.h" #include "Ap4Types.h" /*---------------------------------------------------------------------- -| AP4_VmhdAtom::AP4_VmhdAtom +| AP4_VmhdAtom::Create ++---------------------------------------------------------------------*/ +AP4_VmhdAtom* +AP4_VmhdAtom::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_VmhdAtom(size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_VmhdAtom::AP4_VmhdAtom +---------------------------------------------------------------------*/ AP4_VmhdAtom::AP4_VmhdAtom(AP4_UI16 graphics_mode, AP4_UI16 r, AP4_UI16 g, AP4_UI16 b) : - AP4_Atom(AP4_ATOM_TYPE_VMHD, 8+AP4_FULL_ATOM_HEADER_SIZE, true), + AP4_Atom(AP4_ATOM_TYPE_VMHD, AP4_FULL_ATOM_HEADER_SIZE+8, 0, 0), m_GraphicsMode(graphics_mode) { m_OpColor[0] = r; @@ -48,17 +60,20 @@ AP4_VmhdAtom::AP4_VmhdAtom(AP4_UI16 graphics_mode, AP4_UI16 r, AP4_UI16 g, AP4_U } /*---------------------------------------------------------------------- -| AP4_VmhdAtom::AP4_VmhdAtom +| AP4_VmhdAtom::AP4_VmhdAtom +---------------------------------------------------------------------*/ -AP4_VmhdAtom::AP4_VmhdAtom(AP4_Size size, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_VMHD, size, true, stream) +AP4_VmhdAtom::AP4_VmhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_VMHD, size, version, flags) { stream.ReadUI16(m_GraphicsMode); stream.Read(m_OpColor, sizeof(m_OpColor)); } /*---------------------------------------------------------------------- -| AP4_VmhdAtom::WriteFields +| AP4_VmhdAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_VmhdAtom::WriteFields(AP4_ByteStream& stream) @@ -77,14 +92,14 @@ AP4_VmhdAtom::WriteFields(AP4_ByteStream& stream) } /*---------------------------------------------------------------------- -| AP4_VmhdAtom::InspectFields +| AP4_VmhdAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result AP4_VmhdAtom::InspectFields(AP4_AtomInspector& inspector) { inspector.AddField("graphics_mode", m_GraphicsMode); char formatted[16]; - AP4_StringFormat(formatted, sizeof(formatted), "%04x,%04x,%04x", + AP4_FormatString(formatted, sizeof(formatted), "%04x,%04x,%04x", m_OpColor[0], m_OpColor[1], m_OpColor[2]); inspector.AddField("op_color", formatted); diff --git a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4VmhdAtom.h b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4VmhdAtom.h index 43c8ea2d5..6fed056e3 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4VmhdAtom.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Core/Ap4VmhdAtom.h @@ -2,7 +2,7 @@ | | AP4 - vmhd Atoms | -| Copyright 2002 Gilles Boccon-Gibod +| Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -30,26 +30,31 @@ #define _AP4_VMHD_ATOM_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4.h" -#include "Ap4ByteStream.h" -#include "Ap4Array.h" #include "Ap4Atom.h" /*---------------------------------------------------------------------- -| AP4_VmhdAtom +| AP4_VmhdAtom +---------------------------------------------------------------------*/ class AP4_VmhdAtom : public AP4_Atom { public: + // class methods + static AP4_VmhdAtom* Create(AP4_Size size, AP4_ByteStream& stream); + // methods AP4_VmhdAtom(AP4_UI16 graphics_mode, AP4_UI16 r, AP4_UI16 g, AP4_UI16 b); - AP4_VmhdAtom(AP4_Size size, AP4_ByteStream& stream); virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream); private: + // methods + AP4_VmhdAtom(AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + // members AP4_UI16 m_GraphicsMode; AP4_UI16 m_OpColor[3]; diff --git a/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4AesBlockCipher.cpp b/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4AesBlockCipher.cpp index 95eff4b7e..ef0619901 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4AesBlockCipher.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4AesBlockCipher.cpp @@ -1,1840 +1,1866 @@ -/*
-* AES Block cipher
-* (c) 2005 Gilles Boccon-Gibod
-* Portions (c) 2001, Dr Brian Gladman (see below)
-*/
-
-/*
--------------------------------------------------------------------------
-Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
-All rights reserved.
-
-LICENSE TERMS
-
-The free distribution and use of this software in both source and binary
-form is allowed (with or without changes) provided that:
-
-1. distributions of this source code include the above copyright
-notice, this list of conditions and the following disclaimer;
-
-2. distributions in binary form include the above copyright
-notice, this list of conditions and the following disclaimer
-in the documentation and/or other associated materials;
-
-3. the copyright holder's name is not used to endorse products
-built using this software without specific written permission.
-
-DISCLAIMER
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its properties, including, but not limited to, correctness
-and fitness for purpose.
--------------------------------------------------------------------------
-Issue Date: 29/07/2002
-*/
-
-/*----------------------------------------------------------------------
-| includes
-+---------------------------------------------------------------------*/
-#include "Ap4AesBlockCipher.h"
-#include "Ap4Results.h"
-
-/*----------------------------------------------------------------------
-| build options
-+---------------------------------------------------------------------*/
-#define ENCRYPTION_KEY_SCHEDULE
-#define ENCRYPTION
-#define BLOCK_SIZE AP4_AES_BLOCK_SIZE
-
-/*----------------------------------------------------------------------
-| options
-+---------------------------------------------------------------------*/
-/* START OF CONFIGURATION OPTIONS
-
- USE OF DEFINES
-
- Later in this section there are a number of defines that control the
- operation of the code. In each section, the purpose of each define is
- explained so that the relevant form can be included or excluded by
- setting either 1's or 0's respectively on the branches of the related
- #if clauses.
-*/
-
-/* 1. BYTE ORDER IN 32-BIT WORDS
-
- To obtain the highest speed on processors with 32-bit words, this code
- needs to determine the order in which bytes are packed into such words.
- The following block of code is an attempt to capture the most obvious
- ways in which various environemnts define byte order. It may well fail,
- in which case the definitions will need to be set by editing at the
- points marked **** EDIT HERE IF NECESSARY **** below.
-*/
-#define AES_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
-#define AES_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
-
-#if !defined(AP4_PLATFORM_BYTE_ORDER)
-# error AP4_PLATFORM_BYTE_ORDER is not set
-#endif
-
-#if 0
-#if AP4_PLATFORM_BYTE_ORDER == AP4_PLATFORM_BIG_ENDIAN
-#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#elif AP4_PLATFORM_BYTE_ORDER == AP4_PLATFORM_LITTLE_ENDIAN
-#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#else
-#error unsupported value for AP4_PLATFORM_BYTE_ORDER
-#endif
-#endif
-
-#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-
-
-/* 2. BYTE ORDER WITHIN 32 BIT WORDS
-
- The fundamental data processing units in Rijndael are 8-bit bytes. The
- input, output and key input are all enumerated arrays of bytes in which
- bytes are numbered starting at zero and increasing to one less than the
- number of bytes in the array in question. This enumeration is only used
- for naming bytes and does not imply any adjacency or order relationship
- from one byte to another. When these inputs and outputs are considered
- as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
- byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
- In this implementation bits are numbered from 0 to 7 starting at the
- numerically least significant end of each byte (bit n represents 2^n).
-
- However, Rijndael can be implemented more efficiently using 32-bit
- words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
- into word[n]. While in principle these bytes can be assembled into words
- in any positions, this implementation only supports the two formats in
- which bytes in adjacent positions within words also have adjacent byte
- numbers. This order is called big-endian if the lowest numbered bytes
- in words have the highest numeric significance and little-endian if the
- opposite applies.
-
- This code can work in either order irrespective of the order used by the
- machine on which it runs. Normally the internal byte order will be set
- to the order of the processor on which the code is to be run but this
- define can be used to reverse this in special situations
-*/
-#if 1
-#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
-#elif defined(AES_LITTLE_ENDIAN)
-#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
-#elif defined(AES_BIG_ENDIAN)
-#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
-#endif
-
-/* 3. FAST INPUT/OUTPUT OPERATIONS.
-
- On some machines it is possible to improve speed by transferring the
- bytes in the input and output arrays to and from the internal 32-bit
- variables by addressing these arrays as if they are arrays of 32-bit
- words. On some machines this will always be possible but there may
- be a large performance penalty if the byte arrays are not aligned on
- the normal word boundaries. On other machines this technique will
- lead to memory access errors when such 32-bit word accesses are not
- properly aligned. The option SAFE_IO avoids such problems but will
- often be slower on those machines that support misaligned access
- (especially so if care is taken to align the input and output byte
- arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
- assumed that access to byte arrays as if they are arrays of 32-bit
- words will not cause problems when such accesses are misaligned.
-*/
-#if 1
-#define SAFE_IO
-#endif
-
-/* 4. LOOP UNROLLING
-
- The code for encryption and decrytpion cycles through a number of rounds
- that can be implemented either in a loop or by expanding the code into a
- long sequence of instructions, the latter producing a larger program but
- one that will often be much faster. The latter is called loop unrolling.
- There are also potential speed advantages in expanding two iterations in
- a loop with half the number of iterations, which is called partial loop
- unrolling. The following options allow partial or full loop unrolling
- to be set independently for encryption and decryption
-*/
-#if 1
-#define ENC_UNROLL FULL
-#elif 0
-#define ENC_UNROLL PARTIAL
-#else
-#define ENC_UNROLL NONE
-#endif
-
-#if 1
-#define DEC_UNROLL FULL
-#elif 0
-#define DEC_UNROLL PARTIAL
-#else
-#define DEC_UNROLL NONE
-#endif
-
-/* 5. FIXED OR DYNAMIC TABLES
-
- When this section is included the tables used by the code are comipled
- statically into the binary file. Otherwise they are computed once when
- the code is first used.
-*/
-#if 1
-#define FIXED_TABLES
-#endif
-
-/* 6. FAST FINITE FIELD OPERATIONS
-
- If this section is included, tables are used to provide faster finite
- field arithmetic (this has no effect if FIXED_TABLES is defined).
-*/
-#if 1
-#define FF_TABLES
-#endif
-
-/* 7. INTERNAL STATE VARIABLE FORMAT
-
- The internal state of Rijndael is stored in a number of local 32-bit
- word varaibles which can be defined either as an array or as individual
- names variables. Include this section if you want to store these local
- variables in arrays. Otherwise individual local variables will be used.
-*/
-#if 1
-#define ARRAYS
-#endif
-
-/* In this implementation the columns of the state array are each held in
- 32-bit words. The state array can be held in various ways: in an array
- of words, in a number of individual word variables or in a number of
- processor registers. The following define maps a variable name x and
- a column number c to the way the state array variable is to be held.
- The first define below maps the state into an array x[c] whereas the
- second form maps the state into a number of individual variables x0,
- x1, etc. Another form could map individual state colums to machine
- register names.
-*/
-
-#if defined(ARRAYS)
-#define s(x,c) x[c]
-#else
-#define s(x,c) x##c
-#endif
-
-/* 8. VARIABLE BLOCK SIZE SPEED
-
- This section is only relevant if you wish to use the variable block
- length feature of the code. Include this section if you place more
- emphasis on speed rather than code size.
-*/
-#if 1
-#define FAST_VARIABLE
-#endif
-
-/* 9. INTERNAL TABLE CONFIGURATION
-
- This cipher proceeds by repeating in a number of cycles known as 'rounds'
- which are implemented by a round function which can optionally be speeded
- up using tables. The basic tables are each 256 32-bit words, with either
- one or four tables being required for each round function depending on
- how much speed is required. The encryption and decryption round functions
- are different and the last encryption and decrytpion round functions are
- different again making four different round functions in all.
-
- This means that:
- 1. Normal encryption and decryption rounds can each use either 0, 1
- or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
- 2. The last encryption and decryption rounds can also use either 0, 1
- or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
-
- Include or exclude the appropriate definitions below to set the number
- of tables used by this implementation.
-*/
-
-#if 1 /* set tables for the normal encryption round */
-#define ENC_ROUND FOUR_TABLES
-#elif 0
-#define ENC_ROUND ONE_TABLE
-#else
-#define ENC_ROUND NO_TABLES
-#endif
-
-#if 1 /* set tables for the last encryption round */
-#define LAST_ENC_ROUND FOUR_TABLES
-#elif 0
-#define LAST_ENC_ROUND ONE_TABLE
-#else
-#define LAST_ENC_ROUND NO_TABLES
-#endif
-
-#if 1 /* set tables for the normal decryption round */
-#define DEC_ROUND FOUR_TABLES
-#elif 0
-#define DEC_ROUND ONE_TABLE
-#else
-#define DEC_ROUND NO_TABLES
-#endif
-
-#if 1 /* set tables for the last decryption round */
-#define LAST_DEC_ROUND FOUR_TABLES
-#elif 0
-#define LAST_DEC_ROUND ONE_TABLE
-#else
-#define LAST_DEC_ROUND NO_TABLES
-#endif
-
-/* The decryption key schedule can be speeded up with tables in the same
- way that the round functions can. Include or exclude the following
- defines to set this requirement.
-*/
-#if 1
-#define KEY_SCHED FOUR_TABLES
-#elif 0
-#define KEY_SCHED ONE_TABLE
-#else
-#define KEY_SCHED NO_TABLES
-#endif
-
-/* END OF CONFIGURATION OPTIONS */
-
-#define NO_TABLES 0 /* DO NOT CHANGE */
-#define ONE_TABLE 1 /* DO NOT CHANGE */
-#define FOUR_TABLES 4 /* DO NOT CHANGE */
-#define NONE 0 /* DO NOT CHANGE */
-#define PARTIAL 1 /* DO NOT CHANGE */
-#define FULL 2 /* DO NOT CHANGE */
-
-#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32)
-#error An illegal block size has been specified.
-#endif
-
-#if !defined(BLOCK_SIZE)
-#define RC_LENGTH 29
-#else
-#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11)
-#endif
-
-/* Disable at least some poor combinations of options */
-
-#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
-#undef LAST_ENC_ROUND
-#define LAST_ENC_ROUND NO_TABLES
-#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
-#undef LAST_ENC_ROUND
-#define LAST_ENC_ROUND ONE_TABLE
-#endif
-
-#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
-#undef ENC_UNROLL
-#define ENC_UNROLL NONE
-#endif
-
-#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
-#undef LAST_DEC_ROUND
-#define LAST_DEC_ROUND NO_TABLES
-#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
-#undef LAST_DEC_ROUND
-#define LAST_DEC_ROUND ONE_TABLE
-#endif
-
-#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
-#undef DEC_UNROLL
-#define DEC_UNROLL NONE
-#endif
-
-/* upr(x,n): rotates bytes within words by n positions, moving bytes to
- higher index positions with wrap around into low positions
- ups(x,n): moves bytes by n positions to higher index positions in
- words but without wrap around
- bval(x,n): extracts a byte from a word
-
- NOTE: The definitions given here are intended only for use with
- unsigned variables and with shift counts that are compile
- time constants
-*/
-
-#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
-#if defined(_MSC_VER)
-#define upr(x,n) _lrotl((aes_32t)(x), 8 * (n))
-#else
-#define upr(x,n) ((aes_32t)(x) << 8 * (n) | (aes_32t)(x) >> (32 - 8 * (n)))
-#endif
-#define ups(x,n) ((aes_32t)(x) << 8 * (n))
-#define bval(x,n) ((aes_08t)((x) >> 8 * (n)))
-#define bytes2word(b0, b1, b2, b3) \
- (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0))
-#endif
-
-#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
-#define upr(x,n) ((aes_32t)(x) >> 8 * (n) | (aes_32t)(x) << 32 - 8 * (n))
-#define ups(x,n) ((aes_32t)(x) >> 8 * (n)))
-#define bval(x,n) ((aes_08t)((x) >> (24 - 8 * (n))))
-#define bytes2word(b0, b1, b2, b3) \
- (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3))
-#endif
-
-#if defined(SAFE_IO)
-
-#define word_in(x) bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
-#define word_out(x,v) { (x)[0] = bval(v,0); (x)[1] = bval(v,1); \
- (x)[2] = bval(v,2); (x)[3] = bval(v,3); }
-
-#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
-
-#define word_in(x) *(aes_32t*)(x)
-#define word_out(x,v) *(aes_32t*)(x) = (v)
-
-#else
-
-#if !defined(bswap_32)
-#if !defined(_MSC_VER)
-#define _lrotl(x,n) ((((aes_32t)(x)) << n) | (((aes_32t)(x)) >> (32 - n)))
-#endif
-#define bswap_32(x) ((_lrotl((x),8) & 0x00ff00ff) | (_lrotl((x),24) & 0xff00ff00))
-#endif
-
-#define word_in(x) bswap_32(*(aes_32t*)(x))
-#define word_out(x,v) *(aes_32t*)(x) = bswap_32(v)
-
-#endif
-
-/* the finite field modular polynomial and elements */
-
-#define WPOLY 0x011b
-#define BPOLY 0x1b
-
-/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
-
-#define m1 0x80808080
-#define m2 0x7f7f7f7f
-#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
-
-/* The following defines provide alternative definitions of FFmulX that might
- give improved performance if a fast 32-bit multiply is not available. Note
- that a temporary variable u needs to be defined where FFmulX is used.
-
-#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
-#define m4 (0x01010101 * BPOLY)
-#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
-*/
-
-/* Work out which tables are needed for the different options */
-
-#ifdef AES_ASM
-#ifdef ENC_ROUND
-#undef ENC_ROUND
-#endif
-#define ENC_ROUND FOUR_TABLES
-#ifdef LAST_ENC_ROUND
-#undef LAST_ENC_ROUND
-#endif
-#define LAST_ENC_ROUND FOUR_TABLES
-#ifdef DEC_ROUND
-#undef DEC_ROUND
-#endif
-#define DEC_ROUND FOUR_TABLES
-#ifdef LAST_DEC_ROUND
-#undef LAST_DEC_ROUND
-#endif
-#define LAST_DEC_ROUND FOUR_TABLES
-#ifdef KEY_SCHED
-#undef KEY_SCHED
-#define KEY_SCHED FOUR_TABLES
-#endif
-#endif
-
-#if defined(ENCRYPTION) || defined(AES_ASM)
-#if ENC_ROUND == ONE_TABLE
-#define FT1_SET
-#elif ENC_ROUND == FOUR_TABLES
-#define FT4_SET
-#else
-#define SBX_SET
-#endif
-#if LAST_ENC_ROUND == ONE_TABLE
-#define FL1_SET
-#elif LAST_ENC_ROUND == FOUR_TABLES
-#define FL4_SET
-#elif !defined(SBX_SET)
-#define SBX_SET
-#endif
-#endif
-
-#if defined(DECRYPTION) || defined(AES_ASM)
-#if DEC_ROUND == ONE_TABLE
-#define IT1_SET
-#elif DEC_ROUND == FOUR_TABLES
-#define IT4_SET
-#else
-#define ISB_SET
-#endif
-#if LAST_DEC_ROUND == ONE_TABLE
-#define IL1_SET
-#elif LAST_DEC_ROUND == FOUR_TABLES
-#define IL4_SET
-#elif !defined(ISB_SET)
-#define ISB_SET
-#endif
-#endif
-
-#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
-#if KEY_SCHED == ONE_TABLE
-#define LS1_SET
-#define IM1_SET
-#elif KEY_SCHED == FOUR_TABLES
-#define LS4_SET
-#define IM4_SET
-#elif !defined(SBX_SET)
-#define SBX_SET
-#endif
-#endif
-
-#ifdef FIXED_TABLES
-#define prefx static const
-#else
-#define prefx extern
-extern aes_08t tab_init;
-void gen_tabs(void);
-#endif
-
-//prefx aes_32t rcon_tab[29];
-//
-//#ifdef SBX_SET
-//prefx aes_08t s_box[256];
-//#endif
-//
-//#ifdef ISB_SET
-//prefx aes_08t inv_s_box[256];
-//#endif
-//
-//#ifdef FT1_SET
-//prefx aes_32t ft_tab[256];
-//#endif
-//
-//#ifdef FT4_SET
-//prefx aes_32t ft_tab[4][256];
-//#endif
-//
-//#ifdef FL1_SET
-//prefx aes_32t fl_tab[256];
-//#endif
-//
-//#ifdef FL4_SET
-//prefx aes_32t fl_tab[4][256];
-//#endif
-//
-//#ifdef IT1_SET
-//prefx aes_32t it_tab[256];
-//#endif
-//
-//#ifdef IT4_SET
-//prefx aes_32t it_tab[4][256];
-//#endif
-//
-//#ifdef IL1_SET
-//prefx aes_32t il_tab[256];
-//#endif
-//
-//#ifdef IL4_SET
-//prefx aes_32t il_tab[4][256];
-//#endif
-//
-//#ifdef LS1_SET
-//#ifdef FL1_SET
-//#undef LS1_SET
-//#else
-//prefx aes_32t ls_tab[256];
-//#endif
-//#endif
-//
-//#ifdef LS4_SET
-//#ifdef FL4_SET
-//#undef LS4_SET
-//#else
-//prefx aes_32t ls_tab[4][256];
-//#endif
-//#endif
-//
-//#ifdef IM1_SET
-//prefx aes_32t im_tab[256];
-//#endif
-//
-//#ifdef IM4_SET
-//prefx aes_32t im_tab[4][256];
-//#endif
-
-/* Set the number of columns in nc. Note that it is important
- that nc is a constant which is known at compile time if the
- highest speed version of the code is needed.
-*/
-
-#if defined(BLOCK_SIZE)
-#define nc (BLOCK_SIZE >> 2)
-#else
-#define nc (cx->n_blk >> 2)
-#endif
-
-/* generic definitions of Rijndael macros that use tables */
-
-#define no_table(x,box,vf,rf,c) bytes2word( \
- box[bval(vf(x,0,c),rf(0,c))], \
- box[bval(vf(x,1,c),rf(1,c))], \
- box[bval(vf(x,2,c),rf(2,c))], \
- box[bval(vf(x,3,c),rf(3,c))])
-
-#define one_table(x,op,tab,vf,rf,c) \
- ( tab[bval(vf(x,0,c),rf(0,c))] \
- ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
- ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
- ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
-
-#define four_tables(x,tab,vf,rf,c) \
- ( tab[0][bval(vf(x,0,c),rf(0,c))] \
- ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
- ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
- ^ tab[3][bval(vf(x,3,c),rf(3,c))])
-
-#define vf1(x,r,c) (x)
-#define rf1(r,c) (r)
-#define rf2(r,c) ((r-c)&3)
-
-/* perform forward and inverse column mix operation on four bytes in long word x in */
-/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
-
-#define dec_fmvars
-#if defined(FM4_SET) /* not currently used */
-#define fwd_mcol(x) four_tables(x,fm_tab,vf1,rf1,0)
-#elif defined(FM1_SET) /* not currently used */
-#define fwd_mcol(x) one_table(x,upr,fm_tab,vf1,rf1,0)
-#else
-#undef dec_fmvars
-#define dec_fmvars aes_32t f1, f2;
-#define fwd_mcol(x) (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1))
-#endif
-
-#define dec_imvars
-#if defined(IM4_SET)
-#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
-#elif defined(IM1_SET)
-#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
-#else
-#undef dec_imvars
-#define dec_imvars aes_32t f2, f4, f8, f9;
-#define inv_mcol(x) \
- (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
- f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
-#endif
-
-#if defined(FL4_SET)
-#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
-#elif defined(LS4_SET)
-#define ls_box(x,c) four_tables(x,ls_tab,vf1,rf2,c)
-#elif defined(FL1_SET)
-#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
-#elif defined(LS1_SET)
-#define ls_box(x,c) one_table(x,upr,ls_tab,vf1,rf2,c)
-#else
-#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
-#endif
-
-/*----------------------------------------------------------------------
-| tables
-+---------------------------------------------------------------------*/
-#if defined(FIXED_TABLES) || !defined(FF_TABLES)
-
-/* finite field arithmetic operations */
-
-#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
-#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
-#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
- ^ (((x>>5) & 4) * WPOLY))
-#define f3(x) (f2(x) ^ x)
-#define f9(x) (f8(x) ^ x)
-#define fb(x) (f8(x) ^ f2(x) ^ x)
-#define fd(x) (f8(x) ^ f4(x) ^ x)
-#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
-
-#endif
-
-#if defined(FIXED_TABLES)
-
-#define sb_data(w) \
- w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
- w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
- w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
- w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
- w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
- w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
- w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
- w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
- w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
- w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
- w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
- w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
- w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
- w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
- w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
- w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
- w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
- w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
- w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
- w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
- w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
- w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
- w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
- w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
- w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
- w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
- w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
- w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
- w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
- w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
- w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
- w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
-
-#define isb_data(w) \
- w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
- w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
- w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
- w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
- w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
- w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
- w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
- w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
- w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
- w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
- w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
- w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
- w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
- w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
- w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
- w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
- w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
- w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
- w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
- w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
- w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
- w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
- w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
- w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
- w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
- w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
- w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
- w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
- w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
- w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
- w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
- w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
-
-#define mm_data(w) \
- w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
- w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
- w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
- w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
- w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
- w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
- w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
- w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
- w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
- w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
- w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
- w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
- w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
- w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
- w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
- w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
- w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
- w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
- w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
- w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
- w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
- w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
- w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
- w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
- w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
- w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
- w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
- w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
- w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
- w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
- w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
- w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
-
-#define h0(x) (x)
-
-/* These defines are used to ensure tables are generated in the
- right format depending on the internal byte order required
-*/
-
-#define w0(p) bytes2word(p, 0, 0, 0)
-#define w1(p) bytes2word(0, p, 0, 0)
-#define w2(p) bytes2word(0, 0, p, 0)
-#define w3(p) bytes2word(0, 0, 0, p)
-
-/* Number of elements required in this table for different
- block and key lengths is:
-
- Rcon Table key length (bytes)
- Length 16 20 24 28 32
- ---------------------
- block 16 | 10 9 8 7 7
- length 20 | 14 11 10 9 9
- (bytes) 24 | 19 15 12 11 11
- 28 | 24 19 16 13 13
- 32 | 29 23 19 17 14
-
- this table can be a table of bytes if the key schedule
- code is adjusted accordingly
-*/
-
-#define u0(p) bytes2word(f2(p), p, p, f3(p))
-#define u1(p) bytes2word(f3(p), f2(p), p, p)
-#define u2(p) bytes2word(p, f3(p), f2(p), p)
-#define u3(p) bytes2word(p, p, f3(p), f2(p))
-
-#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
-#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
-#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
-#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
-
-static const aes_32t rcon_tab[29] =
-{
- w0(0x01), w0(0x02), w0(0x04), w0(0x08),
- w0(0x10), w0(0x20), w0(0x40), w0(0x80),
- w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8),
- w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f),
- w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6),
- w0(0x97), w0(0x35), w0(0x6a), w0(0xd4),
- w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef),
- w0(0xc5)
-};
-
-#ifdef SBX_SET
-static const aes_08t s_box[256] = { sb_data(h0) };
-#endif
-#ifdef ISB_SET
-static const aes_08t inv_s_box[256] = { isb_data(h0) };
-#endif
-
-#ifdef FT1_SET
-static const aes_32t ft_tab[256] = { sb_data(u0) };
-#endif
-#ifdef FT4_SET
-static const aes_32t ft_tab[4][256] =
- { { sb_data(u0) }, { sb_data(u1) }, { sb_data(u2) }, { sb_data(u3) } };
-#endif
-
-#ifdef FL1_SET
-static const aes_32t fl_tab[256] = { sb_data(w0) };
-#endif
-#ifdef FL4_SET
-static const aes_32t fl_tab[4][256] =
- { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
-#endif
-
-#ifdef IT1_SET
-static const aes_32t it_tab[256] = { isb_data(v0) };
-#endif
-#ifdef IT4_SET
-static const aes_32t it_tab[4][256] =
- { { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } };
-#endif
-
-#ifdef IL1_SET
-static const aes_32t il_tab[256] = { isb_data(w0) };
-#endif
-#ifdef IL4_SET
-static const aes_32t il_tab[4][256] =
- { { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } };
-#endif
-
-#ifdef LS1_SET
-static const aes_32t ls_tab[256] = { sb_data(w0) };
-#endif
-#ifdef LS4_SET
-static const aes_32t ls_tab[4][256] =
- { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
-#endif
-
-#ifdef IM1_SET
-static const aes_32t im_tab[256] = { mm_data(v0) };
-#endif
-#ifdef IM4_SET
-static const aes_32t im_tab[4][256] =
- { { mm_data(v0) }, { mm_data(v1) }, { mm_data(v2) }, { mm_data(v3) } };
-#endif
-
-#else /* dynamic table generation */
-
-aes_08t tab_init = 0;
-
-#define const
-
-static aes_32t rcon_tab[RC_LENGTH];
-
-#ifdef SBX_SET
-aes_08t s_box[256];
-#endif
-#ifdef ISB_SET
-aes_08t inv_s_box[256];
-#endif
-
-#ifdef FT1_SET
-aes_32t ft_tab[256];
-#endif
-#ifdef FT4_SET
-aes_32t ft_tab[4][256];
-#endif
-
-#ifdef FL1_SET
-aes_32t fl_tab[256];
-#endif
-#ifdef FL4_SET
-aes_32t fl_tab[4][256];
-#endif
-
-#ifdef IT1_SET
-aes_32t it_tab[256];
-#endif
-#ifdef IT4_SET
-aes_32t it_tab[4][256];
-#endif
-
-#ifdef IL1_SET
-aes_32t il_tab[256];
-#endif
-#ifdef IL4_SET
-aes_32t il_tab[4][256];
-#endif
-
-#ifdef LS1_SET
-aes_32t ls_tab[256];
-#endif
-#ifdef LS4_SET
-aes_32t ls_tab[4][256];
-#endif
-
-#ifdef IM1_SET
-aes_32t im_tab[256];
-#endif
-#ifdef IM4_SET
-aes_32t im_tab[4][256];
-#endif
-
-#if !defined(FF_TABLES)
-
-/* Generate the tables for the dynamic table option
-
- It will generally be sensible to use tables to compute finite
- field multiplies and inverses but where memory is scarse this
- code might sometimes be better. But it only has effect during
- initialisation so its pretty unimportant in overall terms.
-*/
-
-/* return 2 ^ (n - 1) where n is the bit number of the highest bit
- set in x with x in the range 1 < x < 0x00000200. This form is
- used so that locals within fi can be bytes rather than words
-*/
-
-static aes_08t hibit(const aes_32t x)
-{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2));
-
- r |= (r >> 2);
- r |= (r >> 4);
- return (r + 1) >> 1;
-}
-
-/* return the inverse of the finite field element x */
-
-static aes_08t fi(const aes_08t x)
-{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-
- if(x < 2) return x;
-
- for(;;)
- {
- if(!n1) return v1;
-
- while(n2 >= n1)
- {
- n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
- }
-
- if(!n2) return v2;
-
- while(n1 >= n2)
- {
- n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
- }
- }
-}
-
-#else
-
-/* define the finite field multiplies required for Rijndael */
-
-#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
-#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
-#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
-#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
-#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
-#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
-#define fi(x) ((x) ? pow[255 - log[x]]: 0)
-
-#endif
-
-/* The forward and inverse affine transformations used in the S-box */
-
-#define fwd_affine(x) \
- (w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8)))
-
-#define inv_affine(x) \
- (w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8)))
-
-void gen_tabs(void)
-{ aes_32t i, w;
-
-#if defined(FF_TABLES)
-
- aes_08t pow[512], log[256];
-
- /* log and power tables for GF(2^8) finite field with
- WPOLY as modular polynomial - the simplest primitive
- root is 0x03, used here to generate the tables
- */
-
- i = 0; w = 1;
- do
- {
- pow[i] = (aes_08t)w;
- pow[i + 255] = (aes_08t)w;
- log[w] = (aes_08t)i++;
- w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
- }
- while (w != 1);
-
-#endif
-
- for(i = 0, w = 1; i < RC_LENGTH; ++i)
- {
- rcon_tab[i] = bytes2word(w, 0, 0, 0);
- w = f2(w);
- }
-
- for(i = 0; i < 256; ++i)
- { aes_08t b;
-
- b = fwd_affine(fi((aes_08t)i));
- w = bytes2word(f2(b), b, b, f3(b));
-
-#ifdef SBX_SET
- s_box[i] = b;
-#endif
-
-#ifdef FT1_SET /* tables for a normal encryption round */
- ft_tab[i] = w;
-#endif
-#ifdef FT4_SET
- ft_tab[0][i] = w;
- ft_tab[1][i] = upr(w,1);
- ft_tab[2][i] = upr(w,2);
- ft_tab[3][i] = upr(w,3);
-#endif
- w = bytes2word(b, 0, 0, 0);
-
-#ifdef FL1_SET /* tables for last encryption round (may also */
- fl_tab[i] = w; /* be used in the key schedule) */
-#endif
-#ifdef FL4_SET
- fl_tab[0][i] = w;
- fl_tab[1][i] = upr(w,1);
- fl_tab[2][i] = upr(w,2);
- fl_tab[3][i] = upr(w,3);
-#endif
-
-#ifdef LS1_SET /* table for key schedule if fl_tab above is */
- ls_tab[i] = w; /* not of the required form */
-#endif
-#ifdef LS4_SET
- ls_tab[0][i] = w;
- ls_tab[1][i] = upr(w,1);
- ls_tab[2][i] = upr(w,2);
- ls_tab[3][i] = upr(w,3);
-#endif
-
- b = fi(inv_affine((aes_08t)i));
- w = bytes2word(fe(b), f9(b), fd(b), fb(b));
-
-#ifdef IM1_SET /* tables for the inverse mix column operation */
- im_tab[b] = w;
-#endif
-#ifdef IM4_SET
- im_tab[0][b] = w;
- im_tab[1][b] = upr(w,1);
- im_tab[2][b] = upr(w,2);
- im_tab[3][b] = upr(w,3);
-#endif
-
-#ifdef ISB_SET
- inv_s_box[i] = b;
-#endif
-#ifdef IT1_SET /* tables for a normal decryption round */
- it_tab[i] = w;
-#endif
-#ifdef IT4_SET
- it_tab[0][i] = w;
- it_tab[1][i] = upr(w,1);
- it_tab[2][i] = upr(w,2);
- it_tab[3][i] = upr(w,3);
-#endif
- w = bytes2word(b, 0, 0, 0);
-#ifdef IL1_SET /* tables for last decryption round */
- il_tab[i] = w;
-#endif
-#ifdef IL4_SET
- il_tab[0][i] = w;
- il_tab[1][i] = upr(w,1);
- il_tab[2][i] = upr(w,2);
- il_tab[3][i] = upr(w,3);
-#endif
- }
-
- tab_init = 1;
-}
-
-#endif
-
-/*----------------------------------------------------------------------
-| key schedule
-+---------------------------------------------------------------------*/
-#if !defined(BLOCK_SIZE)
-
-static aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
-{
-#if !defined(FIXED_TABLES)
- if(!tab_init) gen_tabs();
-#endif
-
- if((blen & 7) || blen < 16 || blen > 32)
- {
- cx->n_blk = 0; return aes_bad;
- }
-
- cx->n_blk = blen;
- return aes_good;
-}
-
-#endif
-
-/* Initialise the key schedule from the user supplied key. The key
- length is now specified in bytes - 16, 24 or 32 as appropriate.
- This corresponds to bit lengths of 128, 192 and 256 bits, and
- to Nk values of 4, 6 and 8 respectively.
-
- The following macros implement a single cycle in the key
- schedule generation process. The number of cycles needed
- for each cx->n_col and nk value is:
-
- nk = 4 5 6 7 8
- ------------------------------
- cx->n_col = 4 10 9 8 7 7
- cx->n_col = 5 14 11 10 9 9
- cx->n_col = 6 19 15 12 11 11
- cx->n_col = 7 21 19 16 13 14
- cx->n_col = 8 29 23 19 17 14
-*/
-
-#define ke4(k,i) \
-{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
- k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
-}
-#define kel4(k,i) \
-{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
- k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
-}
-
-#define ke6(k,i) \
-{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
- k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
- k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
-}
-#define kel6(k,i) \
-{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
- k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
-}
-
-#define ke8(k,i) \
-{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
- k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
- k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
- k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
-}
-#define kel8(k,i) \
-{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
- k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
-}
-
-#if defined(ENCRYPTION_KEY_SCHEDULE)
-
-static aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
-{ aes_32t ss[8];
-
-#if !defined(FIXED_TABLES)
- if(!tab_init) gen_tabs();
-#endif
-
-#if !defined(BLOCK_SIZE)
- if(!cx->n_blk) cx->n_blk = 16;
-#else
- cx->n_blk = BLOCK_SIZE;
-#endif
-
- cx->n_blk = (cx->n_blk & ~3) | 1;
-
- cx->k_sch[0] = ss[0] = word_in(in_key );
- cx->k_sch[1] = ss[1] = word_in(in_key + 4);
- cx->k_sch[2] = ss[2] = word_in(in_key + 8);
- cx->k_sch[3] = ss[3] = word_in(in_key + 12);
-
-#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE)
-
- switch(klen)
- {
- case 16: ke4(cx->k_sch, 0); ke4(cx->k_sch, 1);
- ke4(cx->k_sch, 2); ke4(cx->k_sch, 3);
- ke4(cx->k_sch, 4); ke4(cx->k_sch, 5);
- ke4(cx->k_sch, 6); ke4(cx->k_sch, 7);
- ke4(cx->k_sch, 8); kel4(cx->k_sch, 9);
- cx->n_rnd = 10; break;
- case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
- cx->k_sch[5] = ss[5] = word_in(in_key + 20);
- ke6(cx->k_sch, 0); ke6(cx->k_sch, 1);
- ke6(cx->k_sch, 2); ke6(cx->k_sch, 3);
- ke6(cx->k_sch, 4); ke6(cx->k_sch, 5);
- ke6(cx->k_sch, 6); kel6(cx->k_sch, 7);
- cx->n_rnd = 12; break;
- case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
- cx->k_sch[5] = ss[5] = word_in(in_key + 20);
- cx->k_sch[6] = ss[6] = word_in(in_key + 24);
- cx->k_sch[7] = ss[7] = word_in(in_key + 28);
- ke8(cx->k_sch, 0); ke8(cx->k_sch, 1);
- ke8(cx->k_sch, 2); ke8(cx->k_sch, 3);
- ke8(cx->k_sch, 4); ke8(cx->k_sch, 5);
- kel8(cx->k_sch, 6);
- cx->n_rnd = 14; break;
- default: cx->n_rnd = 0; return aes_bad;
- }
-#else
- { aes_32t i, l;
- cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
- l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
-
- switch(klen)
- {
- case 16: for(i = 0; i < l; ++i)
- ke4(cx->k_sch, i);
- break;
- case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
- cx->k_sch[5] = ss[5] = word_in(in_key + 20);
- for(i = 0; i < l; ++i)
- ke6(cx->k_sch, i);
- break;
- case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
- cx->k_sch[5] = ss[5] = word_in(in_key + 20);
- cx->k_sch[6] = ss[6] = word_in(in_key + 24);
- cx->k_sch[7] = ss[7] = word_in(in_key + 28);
- for(i = 0; i < l; ++i)
- ke8(cx->k_sch, i);
- break;
- default: cx->n_rnd = 0; return aes_bad;
- }
- }
-#endif
-
- return aes_good;
-}
-
-#endif
-
-#if defined(DECRYPTION_KEY_SCHEDULE)
-
-#if (DEC_ROUND != NO_TABLES)
-#define d_vars dec_imvars
-#define ff(x) inv_mcol(x)
-#else
-#define ff(x) (x)
-#define d_vars
-#endif
-
-#if 1
-#define kdf4(k,i) \
-{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
- ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
- ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
- ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
-}
-#define kd4(k,i) \
-{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
- k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
- k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
-}
-#define kdl4(k,i) \
-{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
- k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
- k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
-}
-#else
-#define kdf4(k,i) \
-{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
- ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
-}
-#define kd4(k,i) \
-{ ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \
- ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
- ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
- ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
- ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
-}
-#define kdl4(k,i) \
-{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
- ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
-}
-#endif
-
-#define kdf6(k,i) \
-{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
- ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
- ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
-}
-#define kd6(k,i) \
-{ ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \
- ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
- ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
- ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
- ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
- ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
- ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
-}
-#define kdl6(k,i) \
-{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
- ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
-}
-
-#define kdf8(k,i) \
-{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
- ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
- ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
- ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
-}
-#define kd8(k,i) \
-{ aes_32t g = ls_box(ss[7],3) ^ rcon_tab[i]; \
- ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
- ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
- ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
- ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
- g = ls_box(ss[3],0); \
- ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
- ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
- ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
- ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
-}
-#define kdl8(k,i) \
-{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
- ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
-}
-
-static aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
-{ aes_32t ss[8];
- d_vars
-
-#if !defined(FIXED_TABLES)
- if(!tab_init) gen_tabs();
-#endif
-
-#if !defined(BLOCK_SIZE)
- if(!cx->n_blk) cx->n_blk = 16;
-#else
- cx->n_blk = BLOCK_SIZE;
-#endif
-
- cx->n_blk = (cx->n_blk & ~3) | 2;
-
- cx->k_sch[0] = ss[0] = word_in(in_key );
- cx->k_sch[1] = ss[1] = word_in(in_key + 4);
- cx->k_sch[2] = ss[2] = word_in(in_key + 8);
- cx->k_sch[3] = ss[3] = word_in(in_key + 12);
-
-#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE)
-
- switch(klen)
- {
- case 16: kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1);
- kd4(cx->k_sch, 2); kd4(cx->k_sch, 3);
- kd4(cx->k_sch, 4); kd4(cx->k_sch, 5);
- kd4(cx->k_sch, 6); kd4(cx->k_sch, 7);
- kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9);
- cx->n_rnd = 10; break;
- case 24: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
- cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
- kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1);
- kd6(cx->k_sch, 2); kd6(cx->k_sch, 3);
- kd6(cx->k_sch, 4); kd6(cx->k_sch, 5);
- kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7);
- cx->n_rnd = 12; break;
- case 32: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
- cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
- cx->k_sch[6] = ff(ss[6] = word_in(in_key + 24));
- cx->k_sch[7] = ff(ss[7] = word_in(in_key + 28));
- kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1);
- kd8(cx->k_sch, 2); kd8(cx->k_sch, 3);
- kd8(cx->k_sch, 4); kd8(cx->k_sch, 5);
- kdl8(cx->k_sch, 6);
- cx->n_rnd = 14; break;
- default: cx->n_rnd = 0; return aes_bad;
- }
-#else
- { aes_32t i, l;
- cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
- l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
-
- switch(klen)
- {
- case 16:
- for(i = 0; i < l; ++i)
- ke4(cx->k_sch, i);
- break;
- case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
- cx->k_sch[5] = ss[5] = word_in(in_key + 20);
- for(i = 0; i < l; ++i)
- ke6(cx->k_sch, i);
- break;
- case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
- cx->k_sch[5] = ss[5] = word_in(in_key + 20);
- cx->k_sch[6] = ss[6] = word_in(in_key + 24);
- cx->k_sch[7] = ss[7] = word_in(in_key + 28);
- for(i = 0; i < l; ++i)
- ke8(cx->k_sch, i);
- break;
- default: cx->n_rnd = 0; return aes_bad;
- }
-#if (DEC_ROUND != NO_TABLES)
- for(i = nc; i < nc * cx->n_rnd; ++i)
- cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
-#endif
- }
-#endif
-
- return aes_good;
-}
-
-#endif
-
-/*----------------------------------------------------------------------
-| cipher
-+---------------------------------------------------------------------*/
-#define unused 77 /* Sunset Strip */
-
-#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
-#define so(y,x,c) word_out(y + 4 * c, s(x,c))
-
-#if BLOCK_SIZE == 16
-
-#if defined(ARRAYS)
-#define locals(y,x) x[4],y[4]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
- /*
- the following defines prevent the compiler requiring the declaration
- of generated but unused variables in the fwd_var and inv_var macros
- */
-#define b04 unused
-#define b05 unused
-#define b06 unused
-#define b07 unused
-#define b14 unused
-#define b15 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-
-#elif BLOCK_SIZE == 24
-
-#if defined(ARRAYS)
-#define locals(y,x) x[6],y[6]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
- y##0,y##1,y##2,y##3,y##4,y##5
-#define b06 unused
-#define b07 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3); \
- s(y,4) = s(x,4); s(y,5) = s(x,5);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
- si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
- so(y,x,3); so(y,x,4); so(y,x,5)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
- rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
-#else
-
-#if defined(ARRAYS)
-#define locals(y,x) x[8],y[8]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
- y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
-#endif
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3); \
- s(y,4) = s(x,4); s(y,5) = s(x,5); \
- s(y,6) = s(x,6); s(y,7) = s(x,7);
-
-#if BLOCK_SIZE == 32
-
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
- si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
- so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
- rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
-#else
-
-#define state_in(y,x,k) \
-switch(nc) \
-{ case 8: si(y,x,k,7); si(y,x,k,6); \
- case 6: si(y,x,k,5); si(y,x,k,4); \
- case 4: si(y,x,k,3); si(y,x,k,2); \
- si(y,x,k,1); si(y,x,k,0); \
-}
-
-#define state_out(y,x) \
-switch(nc) \
-{ case 8: so(y,x,7); so(y,x,6); \
- case 6: so(y,x,5); so(y,x,4); \
- case 4: so(y,x,3); so(y,x,2); \
- so(y,x,1); so(y,x,0); \
-}
-
-#if defined(FAST_VARIABLE)
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
- rm(y,x,k,5); rm(y,x,k,4); \
- rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
- break; \
- case 6: rm(y,x,k,5); rm(y,x,k,4); \
- rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
- break; \
- case 4: rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
- break; \
-}
-#else
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
- case 6: rm(y,x,k,5); rm(y,x,k,4); \
- case 4: rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
-}
-
-#endif
-
-#endif
-#endif
-
-#if defined(ENCRYPTION)
-
-/* I am grateful to Frank Yellin for the following construction
- (and that for decryption) which, given the column (c) of the
- output state variable, gives the input state variables which
- are needed in its computation for each row (r) of the state.
-
- For the fixed block size options, compilers should be able to
- reduce this complex expression (and the equivalent one for
- decryption) to a static variable reference at compile time.
- But for variable block size code, there will be some limbs on
- which conditional clauses will be returned.
-*/
-
-/* y = output word, x = input word, r = row, c = column for r = 0,
- 1, 2 and 3 = column accessed for row r.
-*/
-
-#define fwd_var(x,r,c)\
- ( r == 0 ? \
- ( c == 0 ? s(x,0) \
- : c == 1 ? s(x,1) \
- : c == 2 ? s(x,2) \
- : c == 3 ? s(x,3) \
- : c == 4 ? s(x,4) \
- : c == 5 ? s(x,5) \
- : c == 6 ? s(x,6) \
- : s(x,7))\
- : r == 1 ? \
- ( c == 0 ? s(x,1) \
- : c == 1 ? s(x,2) \
- : c == 2 ? s(x,3) \
- : c == 3 ? nc == 4 ? s(x,0) : s(x,4) \
- : c == 4 ? s(x,5) \
- : c == 5 ? nc == 8 ? s(x,6) : s(x,0) \
- : c == 6 ? s(x,7) \
- : s(x,0))\
- : r == 2 ? \
- ( c == 0 ? nc == 8 ? s(x,3) : s(x,2) \
- : c == 1 ? nc == 8 ? s(x,4) : s(x,3) \
- : c == 2 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
- : c == 3 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
- : c == 4 ? nc == 8 ? s(x,7) : s(x,0) \
- : c == 5 ? nc == 8 ? s(x,0) : s(x,1) \
- : c == 6 ? s(x,1) \
- : s(x,2))\
- : \
- ( c == 0 ? nc == 8 ? s(x,4) : s(x,3) \
- : c == 1 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
- : c == 2 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
- : c == 3 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,7) : s(x,0) \
- : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
- : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
- : c == 6 ? s(x,2) \
- : s(x,3)))
-
-#if defined(FT4_SET)
-#undef dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
-#elif defined(FT1_SET)
-#undef dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
-#else
-#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
-#endif
-
-#if defined(FL4_SET)
-#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
-#elif defined(FL1_SET)
-#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
-#else
-#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
-#endif
-
-static aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
-{ aes_32t locals(b0, b1);
- const aes_32t *kp = cx->k_sch;
- dec_fmvars /* declare variables for fwd_mcol() if needed */
-
- if(!(cx->n_blk & 1)) return aes_bad;
-
- state_in(b0, in_blk, kp);
-
-#if (ENC_UNROLL == FULL)
-
- kp += (cx->n_rnd - 9) * nc;
-
- switch(cx->n_rnd)
- {
- case 14: round(fwd_rnd, b1, b0, kp - 4 * nc);
- round(fwd_rnd, b0, b1, kp - 3 * nc);
- case 12: round(fwd_rnd, b1, b0, kp - 2 * nc);
- round(fwd_rnd, b0, b1, kp - nc);
- case 10: round(fwd_rnd, b1, b0, kp );
- round(fwd_rnd, b0, b1, kp + nc);
- round(fwd_rnd, b1, b0, kp + 2 * nc);
- round(fwd_rnd, b0, b1, kp + 3 * nc);
- round(fwd_rnd, b1, b0, kp + 4 * nc);
- round(fwd_rnd, b0, b1, kp + 5 * nc);
- round(fwd_rnd, b1, b0, kp + 6 * nc);
- round(fwd_rnd, b0, b1, kp + 7 * nc);
- round(fwd_rnd, b1, b0, kp + 8 * nc);
- round(fwd_lrnd, b0, b1, kp + 9 * nc);
- }
-#else
-
-#if (ENC_UNROLL == PARTIAL)
- { aes_32t rnd;
- for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
- {
- kp += nc;
- round(fwd_rnd, b1, b0, kp);
- kp += nc;
- round(fwd_rnd, b0, b1, kp);
- }
- kp += nc;
- round(fwd_rnd, b1, b0, kp);
-#else
- { aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
- for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
- {
- kp += nc;
- round(fwd_rnd, p1, p0, kp);
- pt = p0, p0 = p1, p1 = pt;
- }
-#endif
- kp += nc;
- round(fwd_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out_blk, b0);
- return aes_good;
-}
-
-#endif
-
-#if defined(DECRYPTION)
-
-#define inv_var(x,r,c) \
- ( r == 0 ? \
- ( c == 0 ? s(x,0) \
- : c == 1 ? s(x,1) \
- : c == 2 ? s(x,2) \
- : c == 3 ? s(x,3) \
- : c == 4 ? s(x,4) \
- : c == 5 ? s(x,5) \
- : c == 6 ? s(x,6) \
- : s(x,7))\
- : r == 1 ? \
- ( c == 0 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,7) : s(x,5) \
- : c == 1 ? s(x,0) \
- : c == 2 ? s(x,1) \
- : c == 3 ? s(x,2) \
- : c == 4 ? s(x,3) \
- : c == 5 ? s(x,4) \
- : c == 6 ? s(x,5) \
- : s(x,6))\
- : r == 2 ? \
- ( c == 0 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
- : c == 1 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
- : c == 2 ? nc == 8 ? s(x,7) : s(x,0) \
- : c == 3 ? nc == 8 ? s(x,0) : s(x,1) \
- : c == 4 ? nc == 8 ? s(x,1) : s(x,2) \
- : c == 5 ? nc == 8 ? s(x,2) : s(x,3) \
- : c == 6 ? s(x,3) \
- : s(x,4))\
- : \
- ( c == 0 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,4) : s(x,3) \
- : c == 1 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
- : c == 2 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
- : c == 3 ? nc == 8 ? s(x,7) : s(x,0) \
- : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
- : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
- : c == 6 ? s(x,2) \
- : s(x,3)))
-
-#if defined(IT4_SET)
-#undef dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
-#elif defined(IT1_SET)
-#undef dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
-#else
-#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
-#endif
-
-#if defined(IL4_SET)
-#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
-#elif defined(IL1_SET)
-#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
-#else
-#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
-#endif
-
-static aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
-{ aes_32t locals(b0, b1);
- const aes_32t *kp = cx->k_sch + nc * cx->n_rnd;
- dec_imvars /* declare variables for inv_mcol() if needed */
-
- if(!(cx->n_blk & 2)) return aes_bad;
-
- state_in(b0, in_blk, kp);
-
-#if (DEC_UNROLL == FULL)
-
- kp = cx->k_sch + 9 * nc;
- switch(cx->n_rnd)
- {
- case 14: round(inv_rnd, b1, b0, kp + 4 * nc);
- round(inv_rnd, b0, b1, kp + 3 * nc);
- case 12: round(inv_rnd, b1, b0, kp + 2 * nc);
- round(inv_rnd, b0, b1, kp + nc );
- case 10: round(inv_rnd, b1, b0, kp );
- round(inv_rnd, b0, b1, kp - nc);
- round(inv_rnd, b1, b0, kp - 2 * nc);
- round(inv_rnd, b0, b1, kp - 3 * nc);
- round(inv_rnd, b1, b0, kp - 4 * nc);
- round(inv_rnd, b0, b1, kp - 5 * nc);
- round(inv_rnd, b1, b0, kp - 6 * nc);
- round(inv_rnd, b0, b1, kp - 7 * nc);
- round(inv_rnd, b1, b0, kp - 8 * nc);
- round(inv_lrnd, b0, b1, kp - 9 * nc);
- }
-#else
-
-#if (DEC_UNROLL == PARTIAL)
- { aes_32t rnd;
- for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
- {
- kp -= nc;
- round(inv_rnd, b1, b0, kp);
- kp -= nc;
- round(inv_rnd, b0, b1, kp);
- }
- kp -= nc;
- round(inv_rnd, b1, b0, kp);
-#else
- { aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
- for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
- {
- kp -= nc;
- round(inv_rnd, p1, p0, kp);
- pt = p0, p0 = p1, p1 = pt;
- }
-#endif
- kp -= nc;
- round(inv_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out_blk, b0);
- return aes_good;
-}
-
-#endif
-
-/*----------------------------------------------------------------------
-| AP4_AesBlockCipher::AP4_AesBlockCipher
-+---------------------------------------------------------------------*/
-AP4_AesBlockCipher::AP4_AesBlockCipher(const AP4_UI08* key)
-{
- aes_enc_key(key, AP4_AES_KEY_LENGTH, &m_Context);
-}
-
-/*----------------------------------------------------------------------
-| AP4_AesBlockCipher::~AP4_AesBlockCipher
-+---------------------------------------------------------------------*/
-AP4_AesBlockCipher::~AP4_AesBlockCipher()
-{
-}
-
-/*----------------------------------------------------------------------
-| AP4_AesCipher::EncryptBlock
-+---------------------------------------------------------------------*/
-AP4_Result
-AP4_AesBlockCipher::EncryptBlock(const AP4_UI08* block_in, AP4_UI08* block_out)
-{
- aes_rval result;
- result = aes_enc_blk(block_in, block_out, &m_Context);
- return result == aes_good ? AP4_SUCCESS : AP4_FAILURE;
-}
-
+/* +* AES Block cipher +* (c) 2005-2008 Axiomatic Systems,LLC +* Portions (c) 2001, Dr Brian Gladman (see below) +*/ + +/* +------------------------------------------------------------------------- +Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. +All rights reserved. + +LICENSE TERMS + +The free distribution and use of this software in both source and binary +form is allowed (with or without changes) provided that: + +1. distributions of this source code include the above copyright +notice, this list of conditions and the following disclaimer; + +2. distributions in binary form include the above copyright +notice, this list of conditions and the following disclaimer +in the documentation and/or other associated materials; + +3. the copyright holder's name is not used to endorse products +built using this software without specific written permission. + +DISCLAIMER + +This software is provided 'as is' with no explicit or implied warranties +in respect of its properties, including, but not limited to, correctness +and fitness for purpose. +------------------------------------------------------------------------- +Issue Date: 29/07/2002 +*/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4AesBlockCipher.h" +#include "Ap4Results.h" + +/*---------------------------------------------------------------------- +| AES types ++---------------------------------------------------------------------*/ +typedef AP4_UI32 aes_32t; +typedef AP4_UI08 aes_08t; +typedef unsigned int aes_rval; +struct aes_ctx // the AES context for encryption +{ aes_32t k_sch[4*AP4_AES_BLOCK_SIZE]; // the encryption key schedule + aes_32t n_rnd; // the number of cipher rounds + aes_32t n_blk; // the number of bytes in the state +}; +#define aes_bad 0 // bad function return value +#define aes_good 1 // good function return value + +/*---------------------------------------------------------------------- +| build options ++---------------------------------------------------------------------*/ +#define ENCRYPTION_KEY_SCHEDULE +#define ENCRYPTION +#define DECRYPTION_KEY_SCHEDULE +#define DECRYPTION +#define BLOCK_SIZE AP4_AES_BLOCK_SIZE + +/*---------------------------------------------------------------------- +| options ++---------------------------------------------------------------------*/ +/* START OF CONFIGURATION OPTIONS + + USE OF DEFINES + + Later in this section there are a number of defines that control the + operation of the code. In each section, the purpose of each define is + explained so that the relevant form can be included or excluded by + setting either 1's or 0's respectively on the branches of the related + #if clauses. +*/ + +/* 1. BYTE ORDER IN 32-BIT WORDS + + To obtain the highest speed on processors with 32-bit words, this code + needs to determine the order in which bytes are packed into such words. + The following block of code is an attempt to capture the most obvious + ways in which various environemnts define byte order. It may well fail, + in which case the definitions will need to be set by editing at the + points marked **** EDIT HERE IF NECESSARY **** below. +*/ +#define AES_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ +#define AES_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ + +#if !defined(AP4_PLATFORM_BYTE_ORDER) +# error AP4_PLATFORM_BYTE_ORDER is not set +#endif + +#if AP4_PLATFORM_BYTE_ORDER == AP4_PLATFORM_BYTE_ORDER_BIG_ENDIAN +#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN +#elif AP4_PLATFORM_BYTE_ORDER == AP4_PLATFORM_BYTE_ORDER_LITTLE_ENDIAN +#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN +#else +#error unsupported value for AP4_PLATFORM_BYTE_ORDER +#endif + + + +/* 2. BYTE ORDER WITHIN 32 BIT WORDS + + The fundamental data processing units in Rijndael are 8-bit bytes. The + input, output and key input are all enumerated arrays of bytes in which + bytes are numbered starting at zero and increasing to one less than the + number of bytes in the array in question. This enumeration is only used + for naming bytes and does not imply any adjacency or order relationship + from one byte to another. When these inputs and outputs are considered + as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to + byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte. + In this implementation bits are numbered from 0 to 7 starting at the + numerically least significant end of each byte (bit n represents 2^n). + + However, Rijndael can be implemented more efficiently using 32-bit + words by packing bytes into words so that bytes 4*n to 4*n+3 are placed + into word[n]. While in principle these bytes can be assembled into words + in any positions, this implementation only supports the two formats in + which bytes in adjacent positions within words also have adjacent byte + numbers. This order is called big-endian if the lowest numbered bytes + in words have the highest numeric significance and little-endian if the + opposite applies. + + This code can work in either order irrespective of the order used by the + machine on which it runs. Normally the internal byte order will be set + to the order of the processor on which the code is to be run but this + define can be used to reverse this in special situations +*/ +#if 1 +#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER +#elif defined(AES_LITTLE_ENDIAN) +#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN +#elif defined(AES_BIG_ENDIAN) +#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN +#endif + +/* 3. FAST INPUT/OUTPUT OPERATIONS. + + On some machines it is possible to improve speed by transferring the + bytes in the input and output arrays to and from the internal 32-bit + variables by addressing these arrays as if they are arrays of 32-bit + words. On some machines this will always be possible but there may + be a large performance penalty if the byte arrays are not aligned on + the normal word boundaries. On other machines this technique will + lead to memory access errors when such 32-bit word accesses are not + properly aligned. The option SAFE_IO avoids such problems but will + often be slower on those machines that support misaligned access + (especially so if care is taken to align the input and output byte + arrays on 32-bit word boundaries). If SAFE_IO is not defined it is + assumed that access to byte arrays as if they are arrays of 32-bit + words will not cause problems when such accesses are misaligned. +*/ +#if 1 +#define SAFE_IO +#endif + +/* 4. LOOP UNROLLING + + The code for encryption and decrytpion cycles through a number of rounds + that can be implemented either in a loop or by expanding the code into a + long sequence of instructions, the latter producing a larger program but + one that will often be much faster. The latter is called loop unrolling. + There are also potential speed advantages in expanding two iterations in + a loop with half the number of iterations, which is called partial loop + unrolling. The following options allow partial or full loop unrolling + to be set independently for encryption and decryption +*/ +#if 0 +#define ENC_UNROLL FULL +#elif 0 +#define ENC_UNROLL PARTIAL +#else +#define ENC_UNROLL NONE +#endif + +#if 0 +#define DEC_UNROLL FULL +#elif 0 +#define DEC_UNROLL PARTIAL +#else +#define DEC_UNROLL NONE +#endif + +/* 5. FIXED OR DYNAMIC TABLES + + When this section is included the tables used by the code are comipled + statically into the binary file. Otherwise they are computed once when + the code is first used. +*/ +#if 1 +#define FIXED_TABLES +#endif + +/* 6. FAST FINITE FIELD OPERATIONS + + If this section is included, tables are used to provide faster finite + field arithmetic (this has no effect if FIXED_TABLES is defined). +*/ +#if 1 +#define FF_TABLES +#endif + +/* 7. INTERNAL STATE VARIABLE FORMAT + + The internal state of Rijndael is stored in a number of local 32-bit + word varaibles which can be defined either as an array or as individual + names variables. Include this section if you want to store these local + variables in arrays. Otherwise individual local variables will be used. +*/ +#if 1 +#define ARRAYS +#endif + +/* In this implementation the columns of the state array are each held in + 32-bit words. The state array can be held in various ways: in an array + of words, in a number of individual word variables or in a number of + processor registers. The following define maps a variable name x and + a column number c to the way the state array variable is to be held. + The first define below maps the state into an array x[c] whereas the + second form maps the state into a number of individual variables x0, + x1, etc. Another form could map individual state colums to machine + register names. +*/ + +#if defined(ARRAYS) +#define s(x,c) x[c] +#else +#define s(x,c) x##c +#endif + +/* 8. VARIABLE BLOCK SIZE SPEED + + This section is only relevant if you wish to use the variable block + length feature of the code. Include this section if you place more + emphasis on speed rather than code size. +*/ +#if 0 +#define FAST_VARIABLE +#endif + +/* 9. INTERNAL TABLE CONFIGURATION + + This cipher proceeds by repeating in a number of cycles known as 'rounds' + which are implemented by a round function which can optionally be speeded + up using tables. The basic tables are each 256 32-bit words, with either + one or four tables being required for each round function depending on + how much speed is required. The encryption and decryption round functions + are different and the last encryption and decrytpion round functions are + different again making four different round functions in all. + + This means that: + 1. Normal encryption and decryption rounds can each use either 0, 1 + or 4 tables and table spaces of 0, 1024 or 4096 bytes each. + 2. The last encryption and decryption rounds can also use either 0, 1 + or 4 tables and table spaces of 0, 1024 or 4096 bytes each. + + Include or exclude the appropriate definitions below to set the number + of tables used by this implementation. +*/ + +#if 1 /* set tables for the normal encryption round */ +#define ENC_ROUND FOUR_TABLES +#elif 0 +#define ENC_ROUND ONE_TABLE +#else +#define ENC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the last encryption round */ +#define LAST_ENC_ROUND FOUR_TABLES +#elif 0 +#define LAST_ENC_ROUND ONE_TABLE +#else +#define LAST_ENC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the normal decryption round */ +#define DEC_ROUND FOUR_TABLES +#elif 0 +#define DEC_ROUND ONE_TABLE +#else +#define DEC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the last decryption round */ +#define LAST_DEC_ROUND FOUR_TABLES +#elif 0 +#define LAST_DEC_ROUND ONE_TABLE +#else +#define LAST_DEC_ROUND NO_TABLES +#endif + +/* The decryption key schedule can be speeded up with tables in the same + way that the round functions can. Include or exclude the following + defines to set this requirement. +*/ +#if 1 +#define KEY_SCHED FOUR_TABLES +#elif 0 +#define KEY_SCHED ONE_TABLE +#else +#define KEY_SCHED NO_TABLES +#endif + +/* END OF CONFIGURATION OPTIONS */ + +#define NO_TABLES 0 /* DO NOT CHANGE */ +#define ONE_TABLE 1 /* DO NOT CHANGE */ +#define FOUR_TABLES 4 /* DO NOT CHANGE */ +#define NONE 0 /* DO NOT CHANGE */ +#define PARTIAL 1 /* DO NOT CHANGE */ +#define FULL 2 /* DO NOT CHANGE */ + +#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32) +#error An illegal block size has been specified. +#endif + +#if !defined(BLOCK_SIZE) +#define RC_LENGTH 29 +#else +#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11) +#endif + +/* Disable at least some poor combinations of options */ + +#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES +#undef LAST_ENC_ROUND +#define LAST_ENC_ROUND NO_TABLES +#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES +#undef LAST_ENC_ROUND +#define LAST_ENC_ROUND ONE_TABLE +#endif + +#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE +#undef ENC_UNROLL +#define ENC_UNROLL NONE +#endif + +#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES +#undef LAST_DEC_ROUND +#define LAST_DEC_ROUND NO_TABLES +#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES +#undef LAST_DEC_ROUND +#define LAST_DEC_ROUND ONE_TABLE +#endif + +#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE +#undef DEC_UNROLL +#define DEC_UNROLL NONE +#endif + +/* upr(x,n): rotates bytes within words by n positions, moving bytes to + higher index positions with wrap around into low positions + ups(x,n): moves bytes by n positions to higher index positions in + words but without wrap around + bval(x,n): extracts a byte from a word + + NOTE: The definitions given here are intended only for use with + unsigned variables and with shift counts that are compile + time constants +*/ + +#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN) +#if defined(_MSC_VER) +#define upr(x,n) _lrotl((aes_32t)(x), 8 * (n)) +#else +#define upr(x,n) ((aes_32t)(x) << 8 * (n) | (aes_32t)(x) >> (32 - 8 * (n))) +#endif +#define ups(x,n) ((aes_32t)(x) << 8 * (n)) +#define bval(x,n) ((aes_08t)((x) >> 8 * (n))) +#define bytes2word(b0, b1, b2, b3) \ + (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0)) +#endif + +#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN) +#define upr(x,n) ((aes_32t)(x) >> 8 * (n) | (aes_32t)(x) << 32 - 8 * (n)) +#define ups(x,n) ((aes_32t)(x) >> 8 * (n))) +#define bval(x,n) ((aes_08t)((x) >> (24 - 8 * (n)))) +#define bytes2word(b0, b1, b2, b3) \ + (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3)) +#endif + +#if defined(SAFE_IO) + +#define word_in(x) bytes2word((x)[0], (x)[1], (x)[2], (x)[3]) +#define word_out(x,v) { (x)[0] = bval(v,0); (x)[1] = bval(v,1); \ + (x)[2] = bval(v,2); (x)[3] = bval(v,3); } + +#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER) + +#define word_in(x) *(aes_32t*)(x) +#define word_out(x,v) *(aes_32t*)(x) = (v) + +#else + +#if !defined(bswap_32) +#if !defined(_MSC_VER) +#define _lrotl(x,n) ((((aes_32t)(x)) << n) | (((aes_32t)(x)) >> (32 - n))) +#endif +#define bswap_32(x) ((_lrotl((x),8) & 0x00ff00ff) | (_lrotl((x),24) & 0xff00ff00)) +#endif + +#define word_in(x) bswap_32(*(aes_32t*)(x)) +#define word_out(x,v) *(aes_32t*)(x) = bswap_32(v) + +#endif + +/* the finite field modular polynomial and elements */ + +#define WPOLY 0x011b +#define BPOLY 0x1b + +/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + +#define m1 0x80808080 +#define m2 0x7f7f7f7f +#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY)) + +/* The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. Note + that a temporary variable u needs to be defined where FFmulX is used. + +#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6)) +#define m4 (0x01010101 * BPOLY) +#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) +*/ + +/* Work out which tables are needed for the different options */ + +#ifdef AES_ASM +#ifdef ENC_ROUND +#undef ENC_ROUND +#endif +#define ENC_ROUND FOUR_TABLES +#ifdef LAST_ENC_ROUND +#undef LAST_ENC_ROUND +#endif +#define LAST_ENC_ROUND FOUR_TABLES +#ifdef DEC_ROUND +#undef DEC_ROUND +#endif +#define DEC_ROUND FOUR_TABLES +#ifdef LAST_DEC_ROUND +#undef LAST_DEC_ROUND +#endif +#define LAST_DEC_ROUND FOUR_TABLES +#ifdef KEY_SCHED +#undef KEY_SCHED +#define KEY_SCHED FOUR_TABLES +#endif +#endif + +#if defined(ENCRYPTION) || defined(AES_ASM) +#if ENC_ROUND == ONE_TABLE +#define FT1_SET +#elif ENC_ROUND == FOUR_TABLES +#define FT4_SET +#else +#define SBX_SET +#endif +#if LAST_ENC_ROUND == ONE_TABLE +#define FL1_SET +#elif LAST_ENC_ROUND == FOUR_TABLES +#define FL4_SET +#elif !defined(SBX_SET) +#define SBX_SET +#endif +#endif + +#if defined(DECRYPTION) || defined(AES_ASM) +#if DEC_ROUND == ONE_TABLE +#define IT1_SET +#elif DEC_ROUND == FOUR_TABLES +#define IT4_SET +#else +#define ISB_SET +#endif +#if LAST_DEC_ROUND == ONE_TABLE +#define IL1_SET +#elif LAST_DEC_ROUND == FOUR_TABLES +#define IL4_SET +#elif !defined(ISB_SET) +#define ISB_SET +#endif +#endif + +#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE) +#if KEY_SCHED == ONE_TABLE +#define LS1_SET +#define IM1_SET +#elif KEY_SCHED == FOUR_TABLES +#define LS4_SET +#define IM4_SET +#elif !defined(SBX_SET) +#define SBX_SET +#endif +#endif + +#ifdef FIXED_TABLES +#define prefx static const +#else +#define prefx extern +extern aes_08t tab_init; +void gen_tabs(void); +#endif + +//prefx aes_32t rcon_tab[29]; +// +//#ifdef SBX_SET +//prefx aes_08t s_box[256]; +//#endif +// +//#ifdef ISB_SET +//prefx aes_08t inv_s_box[256]; +//#endif +// +//#ifdef FT1_SET +//prefx aes_32t ft_tab[256]; +//#endif +// +//#ifdef FT4_SET +//prefx aes_32t ft_tab[4][256]; +//#endif +// +//#ifdef FL1_SET +//prefx aes_32t fl_tab[256]; +//#endif +// +//#ifdef FL4_SET +//prefx aes_32t fl_tab[4][256]; +//#endif +// +//#ifdef IT1_SET +//prefx aes_32t it_tab[256]; +//#endif +// +//#ifdef IT4_SET +//prefx aes_32t it_tab[4][256]; +//#endif +// +//#ifdef IL1_SET +//prefx aes_32t il_tab[256]; +//#endif +// +//#ifdef IL4_SET +//prefx aes_32t il_tab[4][256]; +//#endif +// +//#ifdef LS1_SET +//#ifdef FL1_SET +//#undef LS1_SET +//#else +//prefx aes_32t ls_tab[256]; +//#endif +//#endif +// +//#ifdef LS4_SET +//#ifdef FL4_SET +//#undef LS4_SET +//#else +//prefx aes_32t ls_tab[4][256]; +//#endif +//#endif +// +//#ifdef IM1_SET +//prefx aes_32t im_tab[256]; +//#endif +// +//#ifdef IM4_SET +//prefx aes_32t im_tab[4][256]; +//#endif + +/* Set the number of columns in nc. Note that it is important + that nc is a constant which is known at compile time if the + highest speed version of the code is needed. +*/ + +#if defined(BLOCK_SIZE) +#define nc (BLOCK_SIZE >> 2) +#else +#define nc (cx->n_blk >> 2) +#endif + +/* generic definitions of Rijndael macros that use tables */ + +#define no_table(x,box,vf,rf,c) bytes2word( \ + box[bval(vf(x,0,c),rf(0,c))], \ + box[bval(vf(x,1,c),rf(1,c))], \ + box[bval(vf(x,2,c),rf(2,c))], \ + box[bval(vf(x,3,c),rf(3,c))]) + +#define one_table(x,op,tab,vf,rf,c) \ + ( tab[bval(vf(x,0,c),rf(0,c))] \ + ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ + ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ + ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) + +#define four_tables(x,tab,vf,rf,c) \ + ( tab[0][bval(vf(x,0,c),rf(0,c))] \ + ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ + ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ + ^ tab[3][bval(vf(x,3,c),rf(3,c))]) + +#define vf1(x,r,c) (x) +#define rf1(r,c) (r) +#define rf2(r,c) ((r-c)&3) + +/* perform forward and inverse column mix operation on four bytes in long word x in */ +/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */ + +#define dec_fmvars +#if defined(FM4_SET) /* not currently used */ +#define fwd_mcol(x) four_tables(x,fm_tab,vf1,rf1,0) +#elif defined(FM1_SET) /* not currently used */ +#define fwd_mcol(x) one_table(x,upr,fm_tab,vf1,rf1,0) +#else +#undef dec_fmvars +#define dec_fmvars aes_32t f1, f2; +#define fwd_mcol(x) (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1)) +#endif + +#define dec_imvars +#if defined(IM4_SET) +#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0) +#elif defined(IM1_SET) +#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0) +#else +#undef dec_imvars +#define dec_imvars aes_32t f2, f4, f8, f9; +#define inv_mcol(x) \ + (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \ + f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1)) +#endif + +#if defined(FL4_SET) +#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c) +#elif defined(LS4_SET) +#define ls_box(x,c) four_tables(x,ls_tab,vf1,rf2,c) +#elif defined(FL1_SET) +#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c) +#elif defined(LS1_SET) +#define ls_box(x,c) one_table(x,upr,ls_tab,vf1,rf2,c) +#else +#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c) +#endif + +/*---------------------------------------------------------------------- +| tables ++---------------------------------------------------------------------*/ +#if defined(FIXED_TABLES) || !defined(FF_TABLES) + +/* finite field arithmetic operations */ + +#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) +#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) +#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \ + ^ (((x>>5) & 4) * WPOLY)) +#define f3(x) (f2(x) ^ x) +#define f9(x) (f8(x) ^ x) +#define fb(x) (f8(x) ^ f2(x) ^ x) +#define fd(x) (f8(x) ^ f4(x) ^ x) +#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) + +#endif + +#if defined(FIXED_TABLES) + +#define sb_data(w) \ + w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ + w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\ + w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\ + w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\ + w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\ + w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\ + w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\ + w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\ + w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\ + w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\ + w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\ + w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\ + w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\ + w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\ + w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\ + w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\ + w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\ + w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\ + w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\ + w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\ + w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\ + w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\ + w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\ + w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\ + w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\ + w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\ + w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\ + w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\ + w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\ + w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\ + w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\ + w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) + +#define isb_data(w) \ + w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\ + w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\ + w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\ + w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\ + w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\ + w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\ + w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\ + w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\ + w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\ + w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\ + w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\ + w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\ + w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\ + w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\ + w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\ + w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\ + w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\ + w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\ + w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\ + w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\ + w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\ + w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\ + w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\ + w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\ + w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\ + w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\ + w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\ + w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\ + w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\ + w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\ + w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\ + w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d), + +#define mm_data(w) \ + w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\ + w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\ + w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\ + w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\ + w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\ + w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\ + w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\ + w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\ + w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\ + w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\ + w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\ + w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\ + w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\ + w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\ + w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\ + w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\ + w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\ + w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\ + w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\ + w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\ + w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\ + w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\ + w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\ + w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\ + w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\ + w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\ + w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\ + w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\ + w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\ + w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\ + w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\ + w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) + +#define h0(x) (x) + +/* These defines are used to ensure tables are generated in the + right format depending on the internal byte order required +*/ + +#define w0(p) bytes2word(p, 0, 0, 0) +#define w1(p) bytes2word(0, p, 0, 0) +#define w2(p) bytes2word(0, 0, p, 0) +#define w3(p) bytes2word(0, 0, 0, p) + +/* Number of elements required in this table for different + block and key lengths is: + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + this table can be a table of bytes if the key schedule + code is adjusted accordingly +*/ + +#define u0(p) bytes2word(f2(p), p, p, f3(p)) +#define u1(p) bytes2word(f3(p), f2(p), p, p) +#define u2(p) bytes2word(p, f3(p), f2(p), p) +#define u3(p) bytes2word(p, p, f3(p), f2(p)) + +#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) +#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) +#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) +#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) + +static const aes_32t rcon_tab[29] = +{ + w0(0x01), w0(0x02), w0(0x04), w0(0x08), + w0(0x10), w0(0x20), w0(0x40), w0(0x80), + w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8), + w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f), + w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6), + w0(0x97), w0(0x35), w0(0x6a), w0(0xd4), + w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef), + w0(0xc5) +}; + +#ifdef SBX_SET +static const aes_08t s_box[256] = { sb_data(h0) }; +#endif +#ifdef ISB_SET +static const aes_08t inv_s_box[256] = { isb_data(h0) }; +#endif + +#ifdef FT1_SET +static const aes_32t ft_tab[256] = { sb_data(u0) }; +#endif +#ifdef FT4_SET +static const aes_32t ft_tab[4][256] = + { { sb_data(u0) }, { sb_data(u1) }, { sb_data(u2) }, { sb_data(u3) } }; +#endif + +#ifdef FL1_SET +static const aes_32t fl_tab[256] = { sb_data(w0) }; +#endif +#ifdef FL4_SET +static const aes_32t fl_tab[4][256] = + { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } }; +#endif + +#ifdef IT1_SET +static const aes_32t it_tab[256] = { isb_data(v0) }; +#endif +#ifdef IT4_SET +static const aes_32t it_tab[4][256] = + { { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } }; +#endif + +#ifdef IL1_SET +static const aes_32t il_tab[256] = { isb_data(w0) }; +#endif +#ifdef IL4_SET +static const aes_32t il_tab[4][256] = + { { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } }; +#endif + +#ifdef LS1_SET +static const aes_32t ls_tab[256] = { sb_data(w0) }; +#endif +#ifdef LS4_SET +static const aes_32t ls_tab[4][256] = + { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } }; +#endif + +#ifdef IM1_SET +static const aes_32t im_tab[256] = { mm_data(v0) }; +#endif +#ifdef IM4_SET +static const aes_32t im_tab[4][256] = + { { mm_data(v0) }, { mm_data(v1) }, { mm_data(v2) }, { mm_data(v3) } }; +#endif + +#else /* dynamic table generation */ + +aes_08t tab_init = 0; + +#define const + +static aes_32t rcon_tab[RC_LENGTH]; + +#ifdef SBX_SET +aes_08t s_box[256]; +#endif +#ifdef ISB_SET +aes_08t inv_s_box[256]; +#endif + +#ifdef FT1_SET +aes_32t ft_tab[256]; +#endif +#ifdef FT4_SET +aes_32t ft_tab[4][256]; +#endif + +#ifdef FL1_SET +aes_32t fl_tab[256]; +#endif +#ifdef FL4_SET +aes_32t fl_tab[4][256]; +#endif + +#ifdef IT1_SET +aes_32t it_tab[256]; +#endif +#ifdef IT4_SET +aes_32t it_tab[4][256]; +#endif + +#ifdef IL1_SET +aes_32t il_tab[256]; +#endif +#ifdef IL4_SET +aes_32t il_tab[4][256]; +#endif + +#ifdef LS1_SET +aes_32t ls_tab[256]; +#endif +#ifdef LS4_SET +aes_32t ls_tab[4][256]; +#endif + +#ifdef IM1_SET +aes_32t im_tab[256]; +#endif +#ifdef IM4_SET +aes_32t im_tab[4][256]; +#endif + +#if !defined(FF_TABLES) + +/* Generate the tables for the dynamic table option + + It will generally be sensible to use tables to compute finite + field multiplies and inverses but where memory is scarse this + code might sometimes be better. But it only has effect during + initialisation so its pretty unimportant in overall terms. +*/ + +/* return 2 ^ (n - 1) where n is the bit number of the highest bit + set in x with x in the range 1 < x < 0x00000200. This form is + used so that locals within fi can be bytes rather than words +*/ + +static aes_08t hibit(const aes_32t x) +{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2)); + + r |= (r >> 2); + r |= (r >> 4); + return (r + 1) >> 1; +} + +/* return the inverse of the finite field element x */ + +static aes_08t fi(const aes_08t x) +{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; + + if(x < 2) return x; + + for(;;) + { + if(!n1) return v1; + + while(n2 >= n1) + { + n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2); + } + + if(!n2) return v2; + + while(n1 >= n2) + { + n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1); + } + } +} + +#else + +/* define the finite field multiplies required for Rijndael */ + +#define f2(x) ((x) ? pow[log[x] + 0x19] : 0) +#define f3(x) ((x) ? pow[log[x] + 0x01] : 0) +#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0) +#define fb(x) ((x) ? pow[log[x] + 0x68] : 0) +#define fd(x) ((x) ? pow[log[x] + 0xee] : 0) +#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0) +#define fi(x) ((x) ? pow[255 - log[x]]: 0) + +#endif + +/* The forward and inverse affine transformations used in the S-box */ + +#define fwd_affine(x) \ + (w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8))) + +#define inv_affine(x) \ + (w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8))) + +void gen_tabs(void) +{ aes_32t i, w; + +#if defined(FF_TABLES) + + aes_08t pow[512], log[256]; + + /* log and power tables for GF(2^8) finite field with + WPOLY as modular polynomial - the simplest primitive + root is 0x03, used here to generate the tables + */ + + i = 0; w = 1; + do + { + pow[i] = (aes_08t)w; + pow[i + 255] = (aes_08t)w; + log[w] = (aes_08t)i++; + w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0); + } + while (w != 1); + +#endif + + for(i = 0, w = 1; i < RC_LENGTH; ++i) + { + rcon_tab[i] = bytes2word(w, 0, 0, 0); + w = f2(w); + } + + for(i = 0; i < 256; ++i) + { aes_08t b; + + b = fwd_affine(fi((aes_08t)i)); + w = bytes2word(f2(b), b, b, f3(b)); + +#ifdef SBX_SET + s_box[i] = b; +#endif + +#ifdef FT1_SET /* tables for a normal encryption round */ + ft_tab[i] = w; +#endif +#ifdef FT4_SET + ft_tab[0][i] = w; + ft_tab[1][i] = upr(w,1); + ft_tab[2][i] = upr(w,2); + ft_tab[3][i] = upr(w,3); +#endif + w = bytes2word(b, 0, 0, 0); + +#ifdef FL1_SET /* tables for last encryption round (may also */ + fl_tab[i] = w; /* be used in the key schedule) */ +#endif +#ifdef FL4_SET + fl_tab[0][i] = w; + fl_tab[1][i] = upr(w,1); + fl_tab[2][i] = upr(w,2); + fl_tab[3][i] = upr(w,3); +#endif + +#ifdef LS1_SET /* table for key schedule if fl_tab above is */ + ls_tab[i] = w; /* not of the required form */ +#endif +#ifdef LS4_SET + ls_tab[0][i] = w; + ls_tab[1][i] = upr(w,1); + ls_tab[2][i] = upr(w,2); + ls_tab[3][i] = upr(w,3); +#endif + + b = fi(inv_affine((aes_08t)i)); + w = bytes2word(fe(b), f9(b), fd(b), fb(b)); + +#ifdef IM1_SET /* tables for the inverse mix column operation */ + im_tab[b] = w; +#endif +#ifdef IM4_SET + im_tab[0][b] = w; + im_tab[1][b] = upr(w,1); + im_tab[2][b] = upr(w,2); + im_tab[3][b] = upr(w,3); +#endif + +#ifdef ISB_SET + inv_s_box[i] = b; +#endif +#ifdef IT1_SET /* tables for a normal decryption round */ + it_tab[i] = w; +#endif +#ifdef IT4_SET + it_tab[0][i] = w; + it_tab[1][i] = upr(w,1); + it_tab[2][i] = upr(w,2); + it_tab[3][i] = upr(w,3); +#endif + w = bytes2word(b, 0, 0, 0); +#ifdef IL1_SET /* tables for last decryption round */ + il_tab[i] = w; +#endif +#ifdef IL4_SET + il_tab[0][i] = w; + il_tab[1][i] = upr(w,1); + il_tab[2][i] = upr(w,2); + il_tab[3][i] = upr(w,3); +#endif + } + + tab_init = 1; +} + +#endif + +/*---------------------------------------------------------------------- +| key schedule ++---------------------------------------------------------------------*/ +#if !defined(BLOCK_SIZE) + +static aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]) +{ +#if !defined(FIXED_TABLES) + if(!tab_init) gen_tabs(); +#endif + + if((blen & 7) || blen < 16 || blen > 32) + { + cx->n_blk = 0; return aes_bad; + } + + cx->n_blk = blen; + return aes_good; +} + +#endif + +/* Initialise the key schedule from the user supplied key. The key + length is now specified in bytes - 16, 24 or 32 as appropriate. + This corresponds to bit lengths of 128, 192 and 256 bits, and + to Nk values of 4, 6 and 8 respectively. + + The following macros implement a single cycle in the key + schedule generation process. The number of cycles needed + for each cx->n_col and nk value is: + + nk = 4 5 6 7 8 + ------------------------------ + cx->n_col = 4 10 9 8 7 7 + cx->n_col = 5 14 11 10 9 9 + cx->n_col = 6 19 15 12 11 11 + cx->n_col = 7 21 19 16 13 14 + cx->n_col = 8 29 23 19 17 14 +*/ + +#define ke4(k,i) \ +{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \ + k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \ +} +#define kel4(k,i) \ +{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \ + k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \ +} + +#define ke6(k,i) \ +{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \ + k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \ + k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \ +} +#define kel6(k,i) \ +{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \ + k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \ +} + +#define ke8(k,i) \ +{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \ + k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \ + k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \ + k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \ +} +#define kel8(k,i) \ +{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \ + k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \ +} + +#if defined(ENCRYPTION_KEY_SCHEDULE) + +static aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]) +{ aes_32t ss[8]; + +#if !defined(FIXED_TABLES) + if(!tab_init) gen_tabs(); +#endif + +#if !defined(BLOCK_SIZE) + if(!cx->n_blk) cx->n_blk = 16; +#else + cx->n_blk = BLOCK_SIZE; +#endif + + cx->n_blk = (cx->n_blk & ~3) | 1; + + cx->k_sch[0] = ss[0] = word_in(in_key ); + cx->k_sch[1] = ss[1] = word_in(in_key + 4); + cx->k_sch[2] = ss[2] = word_in(in_key + 8); + cx->k_sch[3] = ss[3] = word_in(in_key + 12); + +#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE) + + switch(klen) + { + case 16: ke4(cx->k_sch, 0); ke4(cx->k_sch, 1); + ke4(cx->k_sch, 2); ke4(cx->k_sch, 3); + ke4(cx->k_sch, 4); ke4(cx->k_sch, 5); + ke4(cx->k_sch, 6); ke4(cx->k_sch, 7); + ke4(cx->k_sch, 8); kel4(cx->k_sch, 9); + cx->n_rnd = 10; break; + case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + ke6(cx->k_sch, 0); ke6(cx->k_sch, 1); + ke6(cx->k_sch, 2); ke6(cx->k_sch, 3); + ke6(cx->k_sch, 4); ke6(cx->k_sch, 5); + ke6(cx->k_sch, 6); kel6(cx->k_sch, 7); + cx->n_rnd = 12; break; + case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + cx->k_sch[6] = ss[6] = word_in(in_key + 24); + cx->k_sch[7] = ss[7] = word_in(in_key + 28); + ke8(cx->k_sch, 0); ke8(cx->k_sch, 1); + ke8(cx->k_sch, 2); ke8(cx->k_sch, 3); + ke8(cx->k_sch, 4); ke8(cx->k_sch, 5); + kel8(cx->k_sch, 6); + cx->n_rnd = 14; break; + default: cx->n_rnd = 0; return aes_bad; + } +#else + { aes_32t i, l; + cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6; + l = (nc * cx->n_rnd + nc - 1) / (klen >> 2); + + switch(klen) + { + case 16: for(i = 0; i < l; ++i) + ke4(cx->k_sch, i); + break; + case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + for(i = 0; i < l; ++i) + ke6(cx->k_sch, i); + break; + case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + cx->k_sch[6] = ss[6] = word_in(in_key + 24); + cx->k_sch[7] = ss[7] = word_in(in_key + 28); + for(i = 0; i < l; ++i) + ke8(cx->k_sch, i); + break; + default: cx->n_rnd = 0; return aes_bad; + } + } +#endif + + return aes_good; +} + +#endif + +#if defined(DECRYPTION_KEY_SCHEDULE) + +#if (DEC_ROUND != NO_TABLES) +#define d_vars dec_imvars +#define ff(x) inv_mcol(x) +#else +#define ff(x) (x) +#define d_vars +#endif + +#if 1 +#define kdf4(k,i) \ +{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \ + ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \ + ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \ + ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \ +} +#define kd4(k,i) \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \ + k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \ + k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \ +} +#define kdl4(k,i) \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \ + k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \ + k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \ +} +#else +#define kdf4(k,i) \ +{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \ +} +#define kd4(k,i) \ +{ ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \ + ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \ + ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \ + ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \ + ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \ +} +#define kdl4(k,i) \ +{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \ + ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \ +} +#endif + +#define kdf6(k,i) \ +{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \ + ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \ +} +#define kd6(k,i) \ +{ ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \ + ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \ + ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \ + ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \ + ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \ + ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \ + ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \ +} +#define kdl6(k,i) \ +{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \ + ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \ +} + +#define kdf8(k,i) \ +{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \ + ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \ + ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \ +} +#define kd8(k,i) \ +{ aes_32t g = ls_box(ss[7],3) ^ rcon_tab[i]; \ + ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \ + ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \ + ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \ + ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \ + g = ls_box(ss[3],0); \ + ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \ + ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \ + ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \ + ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \ +} +#define kdl8(k,i) \ +{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \ + ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \ +} + +static aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]) +{ aes_32t ss[8]; + d_vars + +#if !defined(FIXED_TABLES) + if(!tab_init) gen_tabs(); +#endif + +#if !defined(BLOCK_SIZE) + if(!cx->n_blk) cx->n_blk = 16; +#else + cx->n_blk = BLOCK_SIZE; +#endif + + cx->n_blk = (cx->n_blk & ~3) | 2; + + cx->k_sch[0] = ss[0] = word_in(in_key ); + cx->k_sch[1] = ss[1] = word_in(in_key + 4); + cx->k_sch[2] = ss[2] = word_in(in_key + 8); + cx->k_sch[3] = ss[3] = word_in(in_key + 12); + +#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE) + + switch(klen) + { + case 16: kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1); + kd4(cx->k_sch, 2); kd4(cx->k_sch, 3); + kd4(cx->k_sch, 4); kd4(cx->k_sch, 5); + kd4(cx->k_sch, 6); kd4(cx->k_sch, 7); + kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9); + cx->n_rnd = 10; break; + case 24: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16)); + cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20)); + kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1); + kd6(cx->k_sch, 2); kd6(cx->k_sch, 3); + kd6(cx->k_sch, 4); kd6(cx->k_sch, 5); + kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7); + cx->n_rnd = 12; break; + case 32: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16)); + cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20)); + cx->k_sch[6] = ff(ss[6] = word_in(in_key + 24)); + cx->k_sch[7] = ff(ss[7] = word_in(in_key + 28)); + kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1); + kd8(cx->k_sch, 2); kd8(cx->k_sch, 3); + kd8(cx->k_sch, 4); kd8(cx->k_sch, 5); + kdl8(cx->k_sch, 6); + cx->n_rnd = 14; break; + default: cx->n_rnd = 0; return aes_bad; + } +#else + { aes_32t i, l; + cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6; + l = (nc * cx->n_rnd + nc - 1) / (klen >> 2); + + switch(klen) + { + case 16: + for(i = 0; i < l; ++i) + ke4(cx->k_sch, i); + break; + case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + for(i = 0; i < l; ++i) + ke6(cx->k_sch, i); + break; + case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + cx->k_sch[6] = ss[6] = word_in(in_key + 24); + cx->k_sch[7] = ss[7] = word_in(in_key + 28); + for(i = 0; i < l; ++i) + ke8(cx->k_sch, i); + break; + default: cx->n_rnd = 0; return aes_bad; + } +#if (DEC_ROUND != NO_TABLES) + for(i = nc; i < nc * cx->n_rnd; ++i) + cx->k_sch[i] = inv_mcol(cx->k_sch[i]); +#endif + } +#endif + + return aes_good; +} + +#endif + +/*---------------------------------------------------------------------- +| cipher ++---------------------------------------------------------------------*/ +#define unused 77 /* Sunset Strip */ + +#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c] +#define so(y,x,c) word_out(y + 4 * c, s(x,c)) + +#if BLOCK_SIZE == 16 + +#if defined(ARRAYS) +#define locals(y,x) x[4],y[4] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 + /* + the following defines prevent the compiler requiring the declaration + of generated but unused variables in the fwd_var and inv_var macros + */ +#define b04 unused +#define b05 unused +#define b06 unused +#define b07 unused +#define b14 unused +#define b15 unused +#define b16 unused +#define b17 unused +#endif +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) + +#elif BLOCK_SIZE == 24 + +#if defined(ARRAYS) +#define locals(y,x) x[6],y[6] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \ + y##0,y##1,y##2,y##3,y##4,y##5 +#define b06 unused +#define b07 unused +#define b16 unused +#define b17 unused +#endif +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); \ + s(y,4) = s(x,4); s(y,5) = s(x,5); +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \ + si(y,x,k,3); si(y,x,k,4); si(y,x,k,5) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \ + so(y,x,3); so(y,x,4); so(y,x,5) +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \ + rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5) +#else + +#if defined(ARRAYS) +#define locals(y,x) x[8],y[8] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \ + y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7 +#endif +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); \ + s(y,4) = s(x,4); s(y,5) = s(x,5); \ + s(y,6) = s(x,6); s(y,7) = s(x,7); + +#if BLOCK_SIZE == 32 + +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \ + si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \ + so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7) +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \ + rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7) +#else + +#define state_in(y,x,k) \ +switch(nc) \ +{ case 8: si(y,x,k,7); si(y,x,k,6); \ + case 6: si(y,x,k,5); si(y,x,k,4); \ + case 4: si(y,x,k,3); si(y,x,k,2); \ + si(y,x,k,1); si(y,x,k,0); \ +} + +#define state_out(y,x) \ +switch(nc) \ +{ case 8: so(y,x,7); so(y,x,6); \ + case 6: so(y,x,5); so(y,x,4); \ + case 4: so(y,x,3); so(y,x,2); \ + so(y,x,1); so(y,x,0); \ +} + +#if defined(FAST_VARIABLE) + +#define round(rm,y,x,k) \ +switch(nc) \ +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ + rm(y,x,k,5); rm(y,x,k,4); \ + rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ + break; \ + case 6: rm(y,x,k,5); rm(y,x,k,4); \ + rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ + break; \ + case 4: rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ + break; \ +} +#else + +#define round(rm,y,x,k) \ +switch(nc) \ +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ + case 6: rm(y,x,k,5); rm(y,x,k,4); \ + case 4: rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ +} + +#endif + +#endif +#endif + +#if defined(ENCRYPTION) + +/* I am grateful to Frank Yellin for the following construction + (and that for decryption) which, given the column (c) of the + output state variable, gives the input state variables which + are needed in its computation for each row (r) of the state. + + For the fixed block size options, compilers should be able to + reduce this complex expression (and the equivalent one for + decryption) to a static variable reference at compile time. + But for variable block size code, there will be some limbs on + which conditional clauses will be returned. +*/ + +/* y = output word, x = input word, r = row, c = column for r = 0, + 1, 2 and 3 = column accessed for row r. +*/ + +#define fwd_var(x,r,c)\ + ( r == 0 ? \ + ( c == 0 ? s(x,0) \ + : c == 1 ? s(x,1) \ + : c == 2 ? s(x,2) \ + : c == 3 ? s(x,3) \ + : c == 4 ? s(x,4) \ + : c == 5 ? s(x,5) \ + : c == 6 ? s(x,6) \ + : s(x,7))\ + : r == 1 ? \ + ( c == 0 ? s(x,1) \ + : c == 1 ? s(x,2) \ + : c == 2 ? s(x,3) \ + : c == 3 ? nc == 4 ? s(x,0) : s(x,4) \ + : c == 4 ? s(x,5) \ + : c == 5 ? nc == 8 ? s(x,6) : s(x,0) \ + : c == 6 ? s(x,7) \ + : s(x,0))\ + : r == 2 ? \ + ( c == 0 ? nc == 8 ? s(x,3) : s(x,2) \ + : c == 1 ? nc == 8 ? s(x,4) : s(x,3) \ + : c == 2 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \ + : c == 3 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \ + : c == 4 ? nc == 8 ? s(x,7) : s(x,0) \ + : c == 5 ? nc == 8 ? s(x,0) : s(x,1) \ + : c == 6 ? s(x,1) \ + : s(x,2))\ + : \ + ( c == 0 ? nc == 8 ? s(x,4) : s(x,3) \ + : c == 1 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \ + : c == 2 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \ + : c == 3 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,7) : s(x,0) \ + : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \ + : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \ + : c == 6 ? s(x,2) \ + : s(x,3))) + +#if defined(FT4_SET) +#undef dec_fmvars +#define dec_fmvars +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c) +#elif defined(FT1_SET) +#undef dec_fmvars +#define dec_fmvars +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c) +#else +#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c] +#endif + +#if defined(FL4_SET) +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c) +#elif defined(FL1_SET) +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c) +#else +#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c] +#endif + +static aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]) +{ aes_32t locals(b0, b1); + const aes_32t *kp = cx->k_sch; + dec_fmvars /* declare variables for fwd_mcol() if needed */ + + if(!(cx->n_blk & 1)) return aes_bad; + + state_in(b0, in_blk, kp); + +#if (ENC_UNROLL == FULL) + + kp += (cx->n_rnd - 9) * nc; + + switch(cx->n_rnd) + { + case 14: round(fwd_rnd, b1, b0, kp - 4 * nc); + round(fwd_rnd, b0, b1, kp - 3 * nc); + case 12: round(fwd_rnd, b1, b0, kp - 2 * nc); + round(fwd_rnd, b0, b1, kp - nc); + case 10: round(fwd_rnd, b1, b0, kp ); + round(fwd_rnd, b0, b1, kp + nc); + round(fwd_rnd, b1, b0, kp + 2 * nc); + round(fwd_rnd, b0, b1, kp + 3 * nc); + round(fwd_rnd, b1, b0, kp + 4 * nc); + round(fwd_rnd, b0, b1, kp + 5 * nc); + round(fwd_rnd, b1, b0, kp + 6 * nc); + round(fwd_rnd, b0, b1, kp + 7 * nc); + round(fwd_rnd, b1, b0, kp + 8 * nc); + round(fwd_lrnd, b0, b1, kp + 9 * nc); + } +#else + +#if (ENC_UNROLL == PARTIAL) + { aes_32t rnd; + for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd) + { + kp += nc; + round(fwd_rnd, b1, b0, kp); + kp += nc; + round(fwd_rnd, b0, b1, kp); + } + kp += nc; + round(fwd_rnd, b1, b0, kp); +#else + { aes_32t rnd, *p0 = b0, *p1 = b1, *pt; + for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd) + { + kp += nc; + round(fwd_rnd, p1, p0, kp); + pt = p0, p0 = p1, p1 = pt; + } +#endif + kp += nc; + round(fwd_lrnd, b0, b1, kp); + } +#endif + + state_out(out_blk, b0); + return aes_good; +} + +#endif + +#if defined(DECRYPTION) + +#define inv_var(x,r,c) \ + ( r == 0 ? \ + ( c == 0 ? s(x,0) \ + : c == 1 ? s(x,1) \ + : c == 2 ? s(x,2) \ + : c == 3 ? s(x,3) \ + : c == 4 ? s(x,4) \ + : c == 5 ? s(x,5) \ + : c == 6 ? s(x,6) \ + : s(x,7))\ + : r == 1 ? \ + ( c == 0 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,7) : s(x,5) \ + : c == 1 ? s(x,0) \ + : c == 2 ? s(x,1) \ + : c == 3 ? s(x,2) \ + : c == 4 ? s(x,3) \ + : c == 5 ? s(x,4) \ + : c == 6 ? s(x,5) \ + : s(x,6))\ + : r == 2 ? \ + ( c == 0 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \ + : c == 1 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \ + : c == 2 ? nc == 8 ? s(x,7) : s(x,0) \ + : c == 3 ? nc == 8 ? s(x,0) : s(x,1) \ + : c == 4 ? nc == 8 ? s(x,1) : s(x,2) \ + : c == 5 ? nc == 8 ? s(x,2) : s(x,3) \ + : c == 6 ? s(x,3) \ + : s(x,4))\ + : \ + ( c == 0 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,4) : s(x,3) \ + : c == 1 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \ + : c == 2 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \ + : c == 3 ? nc == 8 ? s(x,7) : s(x,0) \ + : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \ + : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \ + : c == 6 ? s(x,2) \ + : s(x,3))) + +#if defined(IT4_SET) +#undef dec_imvars +#define dec_imvars +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c) +#elif defined(IT1_SET) +#undef dec_imvars +#define dec_imvars +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c) +#else +#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]) +#endif + +#if defined(IL4_SET) +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c) +#elif defined(IL1_SET) +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c) +#else +#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c] +#endif + +static aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]) +{ aes_32t locals(b0, b1); + const aes_32t *kp = cx->k_sch + nc * cx->n_rnd; + dec_imvars /* declare variables for inv_mcol() if needed */ + + if(!(cx->n_blk & 2)) return aes_bad; + + state_in(b0, in_blk, kp); + +#if (DEC_UNROLL == FULL) + + kp = cx->k_sch + 9 * nc; + switch(cx->n_rnd) + { + case 14: round(inv_rnd, b1, b0, kp + 4 * nc); + round(inv_rnd, b0, b1, kp + 3 * nc); + case 12: round(inv_rnd, b1, b0, kp + 2 * nc); + round(inv_rnd, b0, b1, kp + nc ); + case 10: round(inv_rnd, b1, b0, kp ); + round(inv_rnd, b0, b1, kp - nc); + round(inv_rnd, b1, b0, kp - 2 * nc); + round(inv_rnd, b0, b1, kp - 3 * nc); + round(inv_rnd, b1, b0, kp - 4 * nc); + round(inv_rnd, b0, b1, kp - 5 * nc); + round(inv_rnd, b1, b0, kp - 6 * nc); + round(inv_rnd, b0, b1, kp - 7 * nc); + round(inv_rnd, b1, b0, kp - 8 * nc); + round(inv_lrnd, b0, b1, kp - 9 * nc); + } +#else + +#if (DEC_UNROLL == PARTIAL) + { aes_32t rnd; + for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd) + { + kp -= nc; + round(inv_rnd, b1, b0, kp); + kp -= nc; + round(inv_rnd, b0, b1, kp); + } + kp -= nc; + round(inv_rnd, b1, b0, kp); +#else + { aes_32t rnd, *p0 = b0, *p1 = b1, *pt; + for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd) + { + kp -= nc; + round(inv_rnd, p1, p0, kp); + pt = p0, p0 = p1, p1 = pt; + } +#endif + kp -= nc; + round(inv_lrnd, b0, b1, kp); + } +#endif + + state_out(out_blk, b0); + return aes_good; +} + +#endif + +/*---------------------------------------------------------------------- +| AP4_AesBlockCipher::AP4_AesBlockCipher ++---------------------------------------------------------------------*/ +AP4_AesBlockCipher::AP4_AesBlockCipher(const AP4_UI08* key, + CipherDirection direction) : + m_Direction(direction) +{ + m_Context = new aes_ctx; + if (direction == AP4_BlockCipher::ENCRYPT) { + aes_enc_key(key, AP4_AES_KEY_LENGTH, m_Context); + } else { + aes_dec_key(key, AP4_AES_KEY_LENGTH, m_Context); + } +} + +/*---------------------------------------------------------------------- +| AP4_AesBlockCipher::~AP4_AesBlockCipher ++---------------------------------------------------------------------*/ +AP4_AesBlockCipher::~AP4_AesBlockCipher() +{ + delete m_Context; +} + +/*---------------------------------------------------------------------- +| AP4_AesBlockCipher::EncryptBlock ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AesBlockCipher::ProcessBlock(const AP4_UI08* block_in, + AP4_UI08* block_out) +{ + aes_rval result; + if (m_Direction == AP4_BlockCipher::ENCRYPT) { + result = aes_enc_blk(block_in, block_out, m_Context); + } else { + result = aes_dec_blk(block_in, block_out, m_Context); + } + return result == aes_good ? AP4_SUCCESS : AP4_FAILURE; +} + diff --git a/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4AesBlockCipher.h b/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4AesBlockCipher.h index 71137a063..353cf6473 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4AesBlockCipher.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4AesBlockCipher.h @@ -1,6 +1,6 @@ /* * AES Block cipher - * (c) 2005 Gilles Boccon-Gibod + * (c) 2005-2008 Axiomatic Systems, LLC * Portions (c) 2001, Dr Brian Gladman (see below) */ @@ -37,46 +37,42 @@ #define _AP4_AES_BLOCK_CIPHER_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ #include "Ap4Types.h" #include "Ap4Config.h" +#include "Ap4Protection.h" /*---------------------------------------------------------------------- -| AES constants +| class references +---------------------------------------------------------------------*/ -#define AP4_AES_BLOCK_SIZE 16 -#define AP4_AES_KEY_LENGTH 16 +struct aes_ctx; /*---------------------------------------------------------------------- -| AES types +| AES constants +---------------------------------------------------------------------*/ -typedef AP4_UI32 aes_32t; -typedef AP4_UI08 aes_08t; -typedef unsigned int aes_rval; -typedef struct // the AES context for encryption -{ aes_32t k_sch[4*AP4_AES_BLOCK_SIZE]; // the encryption key schedule - aes_32t n_rnd; // the number of cipher rounds - aes_32t n_blk; // the number of bytes in the state -} aes_ctx; -#define aes_bad 0 // bad function return value -#define aes_good 1 // good function return value +#define AP4_AES_BLOCK_SIZE 16 +#define AP4_AES_KEY_LENGTH 16 /*---------------------------------------------------------------------- -| AP4_AesBlockCipher class +| AP4_AesBlockCipher class +---------------------------------------------------------------------*/ -class AP4_AesBlockCipher +class AP4_AesBlockCipher : public AP4_BlockCipher { - public: +public: // constructor and destructor - AP4_AesBlockCipher(const AP4_UI08* key); + AP4_AesBlockCipher(const AP4_UI08* key, + AP4_BlockCipher::CipherDirection direction); ~AP4_AesBlockCipher(); - // methods - AP4_Result EncryptBlock(const AP4_UI08* block_in, AP4_UI08* block_out); + // AP4_AesBlockCipher methods + virtual AP4_Result ProcessBlock(const AP4_UI08* input, + AP4_UI08* output); - private: - aes_ctx m_Context; +private: + // members + CipherDirection m_Direction; + aes_ctx* m_Context; }; #endif // _AP4_AES_BLOCK_CIPHER_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4StreamCipher.cpp b/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4StreamCipher.cpp index 4352d23d0..0b9320f5c 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4StreamCipher.cpp +++ b/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4StreamCipher.cpp @@ -1,95 +1,95 @@ -/* - * Copyright (c) 2005 Gilles Boccon-Gibod - */ +/***************************************************************** +| +| AP4 - Stream Cipher +| +| 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 +| includes +---------------------------------------------------------------------*/ #include "Ap4StreamCipher.h" +#include "Ap4Utils.h" /*---------------------------------------------------------------------- -| AP4_StreamCipher::AP4_StreamCipher +| AP4_CtrStreamCipher::AP4_CtrStreamCipher +---------------------------------------------------------------------*/ -AP4_StreamCipher::AP4_StreamCipher(const AP4_UI08* key, - const AP4_UI08* salt, - AP4_Size iv_size) : +AP4_CtrStreamCipher::AP4_CtrStreamCipher(AP4_BlockCipher* block_cipher, + const AP4_UI08* salt, + AP4_Size counter_size) : m_StreamOffset(0), - m_IvSize(iv_size), - m_BlockCipher(NULL) + m_CounterSize(counter_size), + m_BlockCipher(block_cipher) { - // clamp the IV size to the max supported size - if (iv_size > 4) { - m_IvSize = 4; + if (m_CounterSize > 16) m_CounterSize = 16; + + // use the salt to initialize the base counter + if (salt) { + // initialize the base counter with a salting key + AP4_CopyMemory(m_BaseCounter, salt, AP4_CIPHER_BLOCK_SIZE); + } else { + // initialize the base counter with zeros + AP4_SetMemory(m_BaseCounter, 0, AP4_CIPHER_BLOCK_SIZE); } - // set the initial state - Reset(key, salt); + // reset the stream offset + SetStreamOffset(0); + SetIV(NULL); } /*---------------------------------------------------------------------- -| AP4_StreamCipher::~AP4_StreamCipher +| AP4_CtrStreamCipher::~AP4_CtrStreamCipher +---------------------------------------------------------------------*/ -AP4_StreamCipher::~AP4_StreamCipher() +AP4_CtrStreamCipher::~AP4_CtrStreamCipher() { - // delete the block cipher - if (m_BlockCipher) { - delete m_BlockCipher; - } + delete m_BlockCipher; } /*---------------------------------------------------------------------- -| AP4_StreamCipher::Reset +| AP4_CtrStreamCipher::SetIV +---------------------------------------------------------------------*/ AP4_Result -AP4_StreamCipher::Reset(const AP4_UI08* key, const AP4_UI08* salt) +AP4_CtrStreamCipher::SetIV(const AP4_UI08* counter) { - if (salt) { - // initialize the counter with a salting key - for (AP4_UI32 i=0; i<AP4_AES_BLOCK_SIZE; i++) { - m_CBlock[i] = salt[i]; - } + if (counter) { + AP4_CopyMemory(&m_BaseCounter[AP4_CIPHER_BLOCK_SIZE-m_CounterSize], + counter, m_CounterSize); } else { - // initialize the counter with no salting key - for (AP4_UI32 i = 0; i < AP4_AES_BLOCK_SIZE; i++) { - m_CBlock[i] = 0; - } - } - - // (re)create the block cipher - if (key != NULL) { - // delete the block cipher if needed - if (m_BlockCipher) { - delete m_BlockCipher; - } - - // (re)create one - m_BlockCipher = DNew AP4_AesBlockCipher(key); + AP4_SetMemory(&m_BaseCounter[AP4_CIPHER_BLOCK_SIZE-m_CounterSize], + 0, m_CounterSize); } - // reset the stream offset - SetStreamOffset(0); - - return AP4_SUCCESS; -} - -/*---------------------------------------------------------------------- -| AP4_StreamCipher::SetCounter -+---------------------------------------------------------------------*/ -void -AP4_StreamCipher::SetCounter(AP4_Offset block_offset) -{ - // set the counter bytes - for (AP4_UI32 i = 0; i < m_IvSize; i++) { - m_CBlock[AP4_AES_BLOCK_SIZE-1-i] = - (AP4_UI08)((block_offset>>(8*i)) & 0xFF); - } + // for the stream offset back to 0 + return SetStreamOffset(0); } /*---------------------------------------------------------------------- -| AP4_StreamCipher::SetStreamOffset +| AP4_CtrStreamCipher::SetStreamOffset +---------------------------------------------------------------------*/ AP4_Result -AP4_StreamCipher::SetStreamOffset(AP4_Offset offset) +AP4_CtrStreamCipher::SetStreamOffset(AP4_UI64 offset, + AP4_Cardinal* preroll) { // do nothing if we're already at that offset if (offset == m_StreamOffset) return AP4_SUCCESS; @@ -99,49 +99,79 @@ AP4_StreamCipher::SetStreamOffset(AP4_Offset offset) // update the key stream if necessary if (m_StreamOffset & 0xF) { - return UpdateKeyStream(m_StreamOffset/AP4_AES_BLOCK_SIZE); + UpdateKeyStream(); } + if (preroll != NULL) *preroll = 0; + return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_StreamCipher::UpdateKeyStream +| AP4_CtrStreamCipher::UpdateKeyStream +---------------------------------------------------------------------*/ -AP4_Result -AP4_StreamCipher::UpdateKeyStream(AP4_Offset block_offset) +void +AP4_CtrStreamCipher::UpdateKeyStream() { + // setup counter offset bytes + AP4_UI64 counter_offset = m_StreamOffset/AP4_CIPHER_BLOCK_SIZE; + AP4_UI08 counter_offset_bytes[8]; + AP4_BytesFromUInt64BE(counter_offset_bytes, counter_offset); + // compute the new counter - SetCounter(block_offset); + AP4_UI08 counter_block[AP4_CIPHER_BLOCK_SIZE]; + unsigned int carry = 0; + for (unsigned int i=0; i<m_CounterSize; i++) { + unsigned int o = AP4_CIPHER_BLOCK_SIZE-1-i; + unsigned int x = m_BaseCounter[o]; + unsigned int y = (i<8)?counter_offset_bytes[7-i]:0; + unsigned int sum = x+y+carry; + counter_block[o] = (AP4_UI08)(sum&0xFF); + carry = ((sum >= 0x100)?1:0); + } + for (unsigned int i=m_CounterSize; i<AP4_CIPHER_BLOCK_SIZE; i++) { + unsigned int o = AP4_CIPHER_BLOCK_SIZE-1-i; + counter_block[o] = m_BaseCounter[o]; + } // compute the key block (x) from the counter block (c) - return m_BlockCipher->EncryptBlock(m_CBlock, m_XBlock); + m_BlockCipher->ProcessBlock(counter_block, m_XBlock); } /*---------------------------------------------------------------------- -| AP4_StreamCipher::ProcessBuffer +| AP4_CtrStreamCipher::ProcessBuffer +---------------------------------------------------------------------*/ AP4_Result -AP4_StreamCipher::ProcessBuffer(const AP4_UI08* in, - AP4_UI08* out, - AP4_Size size) +AP4_CtrStreamCipher::ProcessBuffer(const AP4_UI08* in, + AP4_Size in_size, + AP4_UI08* out, + AP4_Size* out_size /* = NULL */, + bool /* is_last_buffer */) { if (m_BlockCipher == NULL) return AP4_ERROR_INVALID_STATE; + + if (out_size != NULL && *out_size < in_size) { + return AP4_ERROR_BUFFER_TOO_SMALL; + } - while (size) { + // in CTR mode, the output is the same size as the input + if (out_size != NULL) *out_size = in_size; + + // process all the bytes in the buffer + while (in_size) { // compute the number of bytes available in this chunk - AP4_UI32 index = m_StreamOffset & (AP4_AES_BLOCK_SIZE-1); + AP4_UI32 index = (AP4_UI32)(m_StreamOffset & (AP4_CIPHER_BLOCK_SIZE-1)); AP4_UI32 chunk; // update the key stream if we are on a boundary if (index == 0) { - UpdateKeyStream(m_StreamOffset/AP4_AES_BLOCK_SIZE); - chunk = AP4_AES_BLOCK_SIZE; + UpdateKeyStream(); + chunk = AP4_CIPHER_BLOCK_SIZE; } // compute the number of bytes remaining in the chunk - chunk = AP4_AES_BLOCK_SIZE - index; - if (chunk > size) chunk = size; + chunk = AP4_CIPHER_BLOCK_SIZE - index; + if (chunk > in_size) chunk = in_size; // encrypt/decrypt the chunk AP4_UI08* x = &m_XBlock[index]; @@ -151,8 +181,230 @@ AP4_StreamCipher::ProcessBuffer(const AP4_UI08* in, // update offset and size m_StreamOffset += chunk; - size -= chunk; + in_size -= chunk; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_CbcStreamCipher::AP4_CbcStreamCipher ++---------------------------------------------------------------------*/ +AP4_CbcStreamCipher::AP4_CbcStreamCipher(AP4_BlockCipher* block_cipher, + CipherDirection direction) : + m_Direction(direction), + m_StreamOffset(0), + m_OutputSkip(0), + m_BlockCipher(block_cipher), + m_Eos(false), + m_PrerollByteCount(0) +{ + AP4_SetMemory(m_Iv, 0, AP4_CIPHER_BLOCK_SIZE); + AP4_SetMemory(m_OutBlockCache, 0, AP4_CIPHER_BLOCK_SIZE); +} + +/*---------------------------------------------------------------------- +| AP4_CbcStreamCipher::~AP4_CbcStreamCipher ++---------------------------------------------------------------------*/ +AP4_CbcStreamCipher::~AP4_CbcStreamCipher() +{ + delete m_BlockCipher; +} + +/*---------------------------------------------------------------------- +| AP4_CbcStreamCipher::SetIV ++---------------------------------------------------------------------*/ +AP4_Result +AP4_CbcStreamCipher::SetIV(const AP4_UI08* iv) +{ + AP4_CopyMemory(m_Iv, iv, AP4_CIPHER_BLOCK_SIZE); + m_StreamOffset = 0; + m_OutputSkip = 0; + m_Eos = false; + AP4_CopyMemory(m_OutBlockCache, m_Iv, AP4_CIPHER_BLOCK_SIZE); + m_PrerollByteCount = 0; + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_CbcStreamCipher::SetStreamOffset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_CbcStreamCipher::SetStreamOffset(AP4_UI64 offset, + AP4_Cardinal* preroll) +{ + // does not make sense for encryption + if (m_Direction == AP4_StreamCipher::ENCRYPT) return AP4_ERROR_NOT_SUPPORTED; + + // check params + if (preroll == NULL) return AP4_ERROR_INVALID_PARAMETERS; + + // reset the end of stream flag + m_Eos = false; + + // special cases + if (offset == 0) { + *preroll = 0; + return SetIV(m_Iv); } + if (offset == m_StreamOffset) { + *preroll = m_PrerollByteCount; + m_OutputSkip = (AP4_Size)(offset%AP4_CIPHER_BLOCK_SIZE); + return AP4_SUCCESS; + } + + // other cases + if (offset < AP4_CIPHER_BLOCK_SIZE) { + // reset the IV to the output block cache + AP4_CopyMemory(m_OutBlockCache, m_Iv, AP4_CIPHER_BLOCK_SIZE); + m_PrerollByteCount = (AP4_Cardinal) offset; + } else { + m_PrerollByteCount = (AP4_Cardinal) ((offset%AP4_CIPHER_BLOCK_SIZE) + + AP4_CIPHER_BLOCK_SIZE); + } + + *preroll = m_PrerollByteCount; + m_StreamOffset = offset; + m_OutputSkip = (AP4_Size)(offset%AP4_CIPHER_BLOCK_SIZE); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_CbcStreamCipher::ProcessBuffer ++---------------------------------------------------------------------*/ +AP4_Result +AP4_CbcStreamCipher::ProcessBuffer(const AP4_UI08* in, + AP4_Size in_size, + AP4_UI08* out, + AP4_Size* out_size, + bool is_last_buffer /* = false */) +{ + // check the parameters + if (out_size == NULL) return AP4_ERROR_INVALID_PARAMETERS; + + // check the state + if (m_BlockCipher == NULL || m_Eos) { + *out_size = 0; + return AP4_ERROR_INVALID_STATE; + } + if (is_last_buffer) m_Eos = true; + + // if there was a previous call to SetStreamOffset that set m_PrerollByteCount, + // we require that this call provides the at least entire preroll data + if (m_PrerollByteCount) { + if (in_size < m_PrerollByteCount) { + *out_size = 0; + return AP4_ERROR_NOT_ENOUGH_DATA; + } + } + + // compute how many blocks we span + AP4_UI64 start_block = m_StreamOffset/AP4_CIPHER_BLOCK_SIZE; + AP4_UI64 end_block = (m_StreamOffset+in_size-m_PrerollByteCount)/AP4_CIPHER_BLOCK_SIZE; + AP4_UI32 blocks_needed = (AP4_UI32)(end_block-start_block); + + if (m_Direction == ENCRYPT) { + // compute how many blocks we will need to produce + unsigned int padded_in_size = in_size; + AP4_UI08 pad_byte = 0; + if (is_last_buffer) { + ++blocks_needed; + pad_byte = AP4_CIPHER_BLOCK_SIZE-(AP4_UI08)((m_StreamOffset+in_size)%AP4_CIPHER_BLOCK_SIZE); + padded_in_size += pad_byte; + } + if (*out_size < blocks_needed*AP4_CIPHER_BLOCK_SIZE) { + *out_size = blocks_needed*AP4_CIPHER_BLOCK_SIZE; + return AP4_ERROR_BUFFER_TOO_SMALL; + } + *out_size = blocks_needed*AP4_CIPHER_BLOCK_SIZE; + + unsigned int position = (unsigned int)(m_StreamOffset%AP4_CIPHER_BLOCK_SIZE); + m_StreamOffset += in_size; + for (unsigned int x=0; x<padded_in_size; x++) { + if (x < in_size) { + m_InBlockCache[position] = in[x] ^ m_OutBlockCache[position]; + } else { + m_InBlockCache[position] = pad_byte ^ m_OutBlockCache[position]; + } + if (++position == AP4_CIPHER_BLOCK_SIZE) { + // encrypt and emit a block + m_BlockCipher->ProcessBlock(m_InBlockCache, m_OutBlockCache); + AP4_CopyMemory(out, m_OutBlockCache, AP4_CIPHER_BLOCK_SIZE); + out += AP4_CIPHER_BLOCK_SIZE; + position = 0; + } + } + } else { + // compute how many blocks we may produce + AP4_Size bytes_produced = blocks_needed*AP4_CIPHER_BLOCK_SIZE; + if (bytes_produced > m_OutputSkip) { + bytes_produced -= m_OutputSkip; + } + if (*out_size < bytes_produced) { + *out_size = bytes_produced; + return AP4_ERROR_BUFFER_TOO_SMALL; + } + *out_size = bytes_produced; + + // if we've just been seeked (SetStreamOffset), + if (m_PrerollByteCount > 0) { + if (m_PrerollByteCount >= AP4_CIPHER_BLOCK_SIZE) { + // fill the outblock cache with the first 16 bytes + AP4_CopyMemory(m_OutBlockCache, in, AP4_CIPHER_BLOCK_SIZE); + in += AP4_CIPHER_BLOCK_SIZE; + m_PrerollByteCount -= AP4_CIPHER_BLOCK_SIZE; + in_size -= AP4_CIPHER_BLOCK_SIZE; + } + + AP4_ASSERT(m_PrerollByteCount < 16); + + // fill m_InBlockCache with the input for the remaining m_PrerollByteCount + if (m_PrerollByteCount) { + AP4_CopyMemory(m_InBlockCache, in, m_PrerollByteCount); + in += m_PrerollByteCount; + in_size -= m_PrerollByteCount; + m_PrerollByteCount = 0; + } + } + + unsigned int position = (unsigned int)(m_StreamOffset%AP4_CIPHER_BLOCK_SIZE); + m_StreamOffset += in_size; + for (unsigned int x=0; x<in_size; x++) { + m_InBlockCache[position] = in[x]; + if (++position == AP4_CIPHER_BLOCK_SIZE) { + // decrypt a block + AP4_UI08 out_block[AP4_CIPHER_BLOCK_SIZE]; + m_BlockCipher->ProcessBlock(m_InBlockCache, out_block); + for (unsigned int y=0; y<AP4_CIPHER_BLOCK_SIZE; y++) { + out_block[y] ^= m_OutBlockCache[y]; + } + AP4_CopyMemory(m_OutBlockCache, m_InBlockCache, AP4_CIPHER_BLOCK_SIZE); + + // emit the block (or partial block) to the out buffer + unsigned int out_chunk = AP4_CIPHER_BLOCK_SIZE-m_OutputSkip; + AP4_CopyMemory(out, out_block+m_OutputSkip, out_chunk); + out += out_chunk; + position = 0; + m_OutputSkip = 0; + } + } + if (is_last_buffer && m_Direction == DECRYPT) { + // check that we have fed an integral number of blocks + if (m_StreamOffset%AP4_CIPHER_BLOCK_SIZE != 0) { + *out_size = 0; + return AP4_ERROR_INVALID_PARAMETERS; + } + + // remove the padding + AP4_UI08 pad_byte = out[-1]; + if (pad_byte == 0 || pad_byte > AP4_CIPHER_BLOCK_SIZE) { + *out_size = 0; + return AP4_ERROR_INVALID_FORMAT; + } + *out_size -= pad_byte; + } + } + return AP4_SUCCESS; } diff --git a/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4StreamCipher.h b/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4StreamCipher.h index 3328ac6be..9fcec8136 100644 --- a/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4StreamCipher.h +++ b/src/filters/parser/mp4splitter/AP4/Source/Crypto/Ap4StreamCipher.h @@ -1,47 +1,162 @@ -/* - * Copyright (c) 2005 Gilles Boccon-Gibod - */ - +/***************************************************************** +| +| AP4 - Stream Cipher +| +| 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_STREAM_CIPHER_H_ #define _AP4_STREAM_CIPHER_H_ /*---------------------------------------------------------------------- -| includes +| includes +---------------------------------------------------------------------*/ -#include "Ap4AesBlockCipher.h" +#include "Ap4Protection.h" #include "Ap4Results.h" #include "Ap4Types.h" /*---------------------------------------------------------------------- -| AP4_StreamCipher class +| constants ++---------------------------------------------------------------------*/ +// we only support this for now +const unsigned int AP4_CIPHER_BLOCK_SIZE = 16; + +/*---------------------------------------------------------------------- +| AP4_StreamCipher interface +---------------------------------------------------------------------*/ class AP4_StreamCipher { - public: +public: + // types + typedef enum { + ENCRYPT, + DECRYPT + } CipherDirection; + // methods - AP4_StreamCipher(const AP4_UI08* key = NULL, - const AP4_UI08* salt = NULL, - AP4_Size iv_size = 4); - ~AP4_StreamCipher(); - AP4_Result SetStreamOffset(AP4_Offset offset); - AP4_Result Reset(const AP4_UI08* key, const AP4_UI08* salt); - AP4_Result ProcessBuffer(const AP4_UI08* in, - AP4_UI08* out, - AP4_Size size); - AP4_Offset GeStreamOffset() { return m_StreamOffset; } - - private: + virtual ~AP4_StreamCipher() {} + + virtual AP4_UI64 GetStreamOffset() = 0; + + virtual AP4_Result ProcessBuffer(const AP4_UI08* in, + AP4_Size in_size, + AP4_UI08* out, + AP4_Size* out_size, + bool is_last_buffer = false) = 0; + + // preroll gives the number of bytes you have to preroll your input and feed + // it through ProcessBuffer (in one shot) in order to be able to spit out + // the output at the given offset + virtual AP4_Result SetStreamOffset(AP4_UI64 offset, + AP4_Cardinal* preroll) = 0; + + virtual AP4_Result SetIV(const AP4_UI08* iv) = 0; + virtual const AP4_UI08* GetIV() = 0; +}; + + +/*---------------------------------------------------------------------- +| AP4_CtrStreamCipher ++---------------------------------------------------------------------*/ +class AP4_CtrStreamCipher : public AP4_StreamCipher +{ +public: + // methods + + /** + * The block cipher is passed with transfer of ownership (it will + * be destroyed when this object is destroyed). + */ + AP4_CtrStreamCipher(AP4_BlockCipher* block_cipher, + const AP4_UI08* salt, + AP4_Size counter_size); + ~AP4_CtrStreamCipher(); + + // AP4_StreamCipher implementation + virtual AP4_Result SetStreamOffset(AP4_UI64 offset, + AP4_Cardinal* preroll = NULL); + virtual AP4_UI64 GetStreamOffset() { return m_StreamOffset; } + virtual AP4_Result ProcessBuffer(const AP4_UI08* in, + AP4_Size in_size, + AP4_UI08* out, + AP4_Size* out_size = NULL, + bool is_last_buffer = false); + + virtual AP4_Result SetIV(const AP4_UI08* iv); + virtual const AP4_UI08* GetIV() { return m_BaseCounter; } + +private: + // methods + void SetCounterOffset(AP4_UI32 offset); + void UpdateKeyStream(); + // members - AP4_Offset m_StreamOffset; - AP4_Size m_IvSize; - AP4_UI08 m_CBlock[AP4_AES_BLOCK_SIZE]; - AP4_UI08 m_XBlock[AP4_AES_BLOCK_SIZE]; - AP4_AesBlockCipher* m_BlockCipher; + AP4_UI64 m_StreamOffset; + AP4_Size m_CounterSize; + AP4_UI08 m_BaseCounter[AP4_CIPHER_BLOCK_SIZE]; + AP4_UI08 m_XBlock[AP4_CIPHER_BLOCK_SIZE]; + AP4_BlockCipher* m_BlockCipher; +}; +/*---------------------------------------------------------------------- +| AP4_CbcStreamCipher ++---------------------------------------------------------------------*/ +class AP4_CbcStreamCipher : public AP4_StreamCipher +{ +public: // methods - void SetCounter(AP4_Offset block_offset); - AP4_Result UpdateKeyStream(AP4_Offset block_offset); + + /** + * The block cipher is passed with transfer of ownership (it will + * be destroyed when this object is destroyed). + */ + AP4_CbcStreamCipher(AP4_BlockCipher* block_cipher, CipherDirection direction); + ~AP4_CbcStreamCipher(); + + // AP4_StreamCipher implementation + virtual AP4_Result SetStreamOffset(AP4_UI64 offset, + AP4_Cardinal* preroll); + virtual AP4_UI64 GetStreamOffset() { return m_StreamOffset; } + virtual AP4_Result ProcessBuffer(const AP4_UI08* in, + AP4_Size in_size, + AP4_UI08* out, + AP4_Size* out_size, + bool is_last_buffer = false); + virtual AP4_Result SetIV(const AP4_UI08* iv); + virtual const AP4_UI08* GetIV() { return m_Iv; }; + +private: + // members + CipherDirection m_Direction; + AP4_UI64 m_StreamOffset; + AP4_Size m_OutputSkip; + AP4_UI08 m_InBlockCache[AP4_CIPHER_BLOCK_SIZE]; + AP4_UI08 m_OutBlockCache[AP4_CIPHER_BLOCK_SIZE]; + AP4_UI08 m_Iv[AP4_CIPHER_BLOCK_SIZE]; + AP4_BlockCipher* m_BlockCipher; + bool m_Eos; + AP4_Cardinal m_PrerollByteCount; }; #endif // _AP4_STREAM_CIPHER_H_ diff --git a/src/filters/parser/mp4splitter/AP4/Source/MetaData/Ap4MetaData.cpp b/src/filters/parser/mp4splitter/AP4/Source/MetaData/Ap4MetaData.cpp new file mode 100644 index 000000000..eb7a43115 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/MetaData/Ap4MetaData.cpp @@ -0,0 +1,1736 @@ +/***************************************************************** +| +| AP4 - MetaData +| +| 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 "Ap4File.h" +#include "Ap4Movie.h" +#include "Ap4MetaData.h" +#include "Ap4ContainerAtom.h" +#include "Ap4MoovAtom.h" +#include "Ap4HdlrAtom.h" +#include "Ap4DataBuffer.h" +#include "Ap4Utils.h" +#include "Ap4String.h" + +/*---------------------------------------------------------------------- +| dynamic cast support ++---------------------------------------------------------------------*/ +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_3GppLocalizedStringAtom) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_DcfdAtom) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_DcfStringAtom) +AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_DataAtom) + +/*---------------------------------------------------------------------- +| metadata keys ++---------------------------------------------------------------------*/ +static const AP4_MetaData::KeyInfo AP4_MetaData_KeyInfos [] = { + {"Name", "Name", AP4_ATOM_TYPE_cNAM, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Artist", "Artist", AP4_ATOM_TYPE_cART, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"AlbumArtist", "Album Artist", AP4_ATOM_TYPE_aART, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Composer", "Composer", AP4_ATOM_TYPE_cCOM, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Writer", "Writer", AP4_ATOM_TYPE_cWRT, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Album", "Album", AP4_ATOM_TYPE_cALB, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"GenreCode", "Genre", AP4_ATOM_TYPE_GNRE, AP4_MetaData::Value::TYPE_BINARY}, + {"GenreName", "Genre", AP4_ATOM_TYPE_cGEN, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Grouping", "Grouping", AP4_ATOM_TYPE_cGRP, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Date", "Date", AP4_ATOM_TYPE_cDAY, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Tool", "Encoding Tool", AP4_ATOM_TYPE_cTOO, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Comment", "Comment", AP4_ATOM_TYPE_cCMT, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Lyrics", "Lyrics", AP4_ATOM_TYPE_cLYR, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Copyright", "Copyright", AP4_ATOM_TYPE_CPRT, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Track", "Track Number", AP4_ATOM_TYPE_TRKN, AP4_MetaData::Value::TYPE_BINARY}, + {"Disc", "Disc Number", AP4_ATOM_TYPE_DISK, AP4_MetaData::Value::TYPE_BINARY}, + {"Cover", "Cover Art", AP4_ATOM_TYPE_COVR, AP4_MetaData::Value::TYPE_BINARY}, + {"Description", "Description", AP4_ATOM_TYPE_DESC, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Rating", "Rating", AP4_ATOM_TYPE_RTNG, AP4_MetaData::Value::TYPE_INT_08_BE}, + {"Tempo", "Tempo", AP4_ATOM_TYPE_TMPO, AP4_MetaData::Value::TYPE_INT_16_BE}, + {"Compilation", "Compilation", AP4_ATOM_TYPE_CPIL, AP4_MetaData::Value::TYPE_INT_08_BE}, + {"IsGapless", "Is Gapless", AP4_ATOM_TYPE_PGAP, AP4_MetaData::Value::TYPE_INT_08_BE}, + {"Title", "Title", AP4_ATOM_TYPE_TITL, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Description", "Description", AP4_ATOM_TYPE_DSCP, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"StoreFrontID", "Store Front ID", AP4_ATOM_TYPE_sfID, AP4_MetaData::Value::TYPE_INT_32_BE}, + {"FileKind", "File Kind", AP4_ATOM_TYPE_STIK, AP4_MetaData::Value::TYPE_INT_08_BE}, + {"ShowName", "Show Name", AP4_ATOM_TYPE_TVSH, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"ShowSeason", "Show Season Number", AP4_ATOM_TYPE_TVSN, AP4_MetaData::Value::TYPE_INT_32_BE}, + {"ShowEpisodeNumber", "Show Episode Number", AP4_ATOM_TYPE_TVES, AP4_MetaData::Value::TYPE_INT_32_BE}, + {"ShowEpisodeName", "Show Episode Name", AP4_ATOM_TYPE_TVEN, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"TVNetworkName", "TV Network Name", AP4_ATOM_TYPE_TVNN, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"IsPodcast", "Is a Podcast", AP4_ATOM_TYPE_PCST, AP4_MetaData::Value::TYPE_INT_08_BE}, + {"PodcastUrl", "Podcast URL", AP4_ATOM_TYPE_PURL, AP4_MetaData::Value::TYPE_BINARY}, + {"PodcastGuid", "Podcast GUID", AP4_ATOM_TYPE_EGID, AP4_MetaData::Value::TYPE_BINARY}, + {"PodcastCategory", "Podcast Category", AP4_ATOM_TYPE_CATG, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Keywords", "Keywords", AP4_ATOM_TYPE_KEYW, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"PurchaseDate", "Purchase Date", AP4_ATOM_TYPE_PURD, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"IconUri", "Icon URI", AP4_ATOM_TYPE_ICNU, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"InfoUrl", "Info URL", AP4_ATOM_TYPE_INFU, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"CoverUri", "Cover Art URI", AP4_ATOM_TYPE_CVRU, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"LyricsUri", "Lyrics URI", AP4_ATOM_TYPE_LRCU, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Duration", "Duration", AP4_ATOM_TYPE_DCFD, AP4_MetaData::Value::TYPE_INT_32_BE}, + {"Performer", "Performer", AP4_ATOM_TYPE_PERF, AP4_MetaData::Value::TYPE_STRING_UTF_8}, + {"Author", "Author", AP4_ATOM_TYPE_AUTH, AP4_MetaData::Value::TYPE_STRING_UTF_8}, +}; +AP4_Array<AP4_MetaData::KeyInfo> AP4_MetaData::KeyInfos( + AP4_MetaData_KeyInfos, + sizeof(AP4_MetaData_KeyInfos)/sizeof(KeyInfo)); + +/*---------------------------------------------------------------------- +| genre IDs ++---------------------------------------------------------------------*/ +static const char* const Ap4Id3Genres[] = +{ + "Blues", + "Classic Rock", + "Country", + "Dance", + "Disco", + "Funk", + "Grunge", + "Hip-Hop", + "Jazz", + "Metal", + "New Age", + "Oldies", + "Other", + "Pop", + "R&B", + "Rap", + "Reggae", + "Rock", + "Techno", + "Industrial", + "Alternative", + "Ska", + "Death Metal", + "Pranks", + "Soundtrack", + "Euro-Techno", + "Ambient", + "Trip-Hop", + "Vocal", + "Jazz+Funk", + "Fusion", + "Trance", + "Classical", + "Instrumental", + "Acid", + "House", + "Game", + "Sound Clip", + "Gospel", + "Noise", + "AlternRock", + "Bass", + "Soul", + "Punk", + "Space", + "Meditative", + "Instrumental Pop", + "Instrumental Rock", + "Ethnic", + "Gothic", + "Darkwave", + "Techno-Industrial", + "Electronic", + "Pop-Folk", + "Eurodance", + "Dream", + "Southern Rock", + "Comedy", + "Cult", + "Gangsta", + "Top 40", + "Christian Rap", + "Pop/Funk", + "Jungle", + "Native American", + "Cabaret", + "New Wave", + "Psychadelic", + "Rave", + "Showtunes", + "Trailer", + "Lo-Fi", + "Tribal", + "Acid Punk", + "Acid Jazz", + "Polka", + "Retro", + "Musical", + "Rock & Roll", + "Hard Rock", + "Folk", + "Folk-Rock", + "National Folk", + "Swing", + "Fast Fusion", + "Bebob", + "Latin", + "Revival", + "Celtic", + "Bluegrass", + "Avantgarde", + "Gothic Rock", + "Progressive Rock", + "Psychedelic Rock", + "Symphonic Rock", + "Slow Rock", + "Big Band", + "Chorus", + "Easy Listening", + "Acoustic", + "Humour", + "Speech", + "Chanson", + "Opera", + "Chamber Music", + "Sonata", + "Symphony", + "Booty Bass", + "Primus", + "Porn Groove", + "Satire", + "Slow Jam", + "Club", + "Tango", + "Samba", + "Folklore", + "Ballad", + "Power Ballad", + "Rhythmic Soul", + "Freestyle", + "Duet", + "Punk Rock", + "Drum Solo", + "Acapella", + "Euro-House", + "Dance Hall" +}; + +static const char* +Ap4StikNames[] = { + "Movie", // 0 + "Normal", // 1 + "Audiobook", // 2 + "?", // 3 + "?", // 4 + "Whacked Bookmark", // 5 + "Music Video", // 6 + "?", // 7 + "?", // 8 + "Short Film", // 9 + "TV Show", // 10 + "Booklet", // 11 + "?", // 12 + "?", // 13 + "Ring Tone" // 14 +}; + + +/* sfID Store Front country + Australia => 143460, + Austria => 143445, + Belgium => 143446, + Canada => 143455, + Denmark => 143458, + Finland => 143447, + France => 143442, + Germany => 143443, + Greece => 143448, + Ireland => 143449, + Italy => 143450, + Japan => 143462, + Luxembourg => 143451, + Netherlands => 143452, + Norway => 143457, + Portugal => 143453, + Spain => 143454, + Sweden => 143456, + Switzerland => 143459, + UK => 143444, + USA => 143441, +*/ + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const AP4_Size AP4_DATA_ATOM_MAX_SIZE = 0x40000000; + +/*---------------------------------------------------------------------- +| 3GPP localized string atoms ++---------------------------------------------------------------------*/ +const AP4_Atom::Type AP4_MetaDataAtomTypeHandler::_3gppLocalizedStringTypes[] = { + AP4_ATOM_TYPE_TITL, + AP4_ATOM_TYPE_DSCP, + AP4_ATOM_TYPE_CPRT, + AP4_ATOM_TYPE_PERF, + AP4_ATOM_TYPE_AUTH, + AP4_ATOM_TYPE_GNRE +}; +const AP4_MetaDataAtomTypeHandler::TypeList AP4_MetaDataAtomTypeHandler::_3gppLocalizedStringTypeList = { + _3gppLocalizedStringTypes, + sizeof(_3gppLocalizedStringTypes)/sizeof(_3gppLocalizedStringTypes[0]) +}; + +/*---------------------------------------------------------------------- +| other 3GPP atoms ++---------------------------------------------------------------------*/ +const AP4_Atom::Type AP4_MetaDataAtomTypeHandler::_3gppOtherTypes[] = { + AP4_ATOM_TYPE_RTNG, + AP4_ATOM_TYPE_CLSF, + AP4_ATOM_TYPE_KYWD, + AP4_ATOM_TYPE_LOCI, + AP4_ATOM_TYPE_ALBM, + AP4_ATOM_TYPE_YRRC, +}; +const AP4_MetaDataAtomTypeHandler::TypeList AP4_MetaDataAtomTypeHandler::_3gppOtherTypeList = { + _3gppOtherTypes, + sizeof(_3gppOtherTypes)/sizeof(_3gppOtherTypes[0]) +}; + +/*---------------------------------------------------------------------- +| DCF string atoms ++---------------------------------------------------------------------*/ +const AP4_Atom::Type AP4_MetaDataAtomTypeHandler::DcfStringTypes[] = { + AP4_ATOM_TYPE_ICNU, + AP4_ATOM_TYPE_INFU, + AP4_ATOM_TYPE_CVRU, + AP4_ATOM_TYPE_LRCU +}; +const AP4_MetaDataAtomTypeHandler::TypeList AP4_MetaDataAtomTypeHandler::DcfStringTypeList = { + DcfStringTypes, + sizeof(DcfStringTypes)/sizeof(DcfStringTypes[0]) +}; + +/*---------------------------------------------------------------------- +| atom type lists ++---------------------------------------------------------------------*/ +const AP4_Atom::Type AP4_MetaDataAtomTypeHandler::IlstTypes[] = +{ + AP4_ATOM_TYPE_dddd, + AP4_ATOM_TYPE_cNAM, + AP4_ATOM_TYPE_cART, + AP4_ATOM_TYPE_cCOM, + AP4_ATOM_TYPE_cWRT, + AP4_ATOM_TYPE_cALB, + AP4_ATOM_TYPE_cGEN, + AP4_ATOM_TYPE_cGRP, + AP4_ATOM_TYPE_cDAY, + AP4_ATOM_TYPE_cTOO, + AP4_ATOM_TYPE_cCMT, + AP4_ATOM_TYPE_CPRT, + AP4_ATOM_TYPE_TRKN, + AP4_ATOM_TYPE_DISK, + AP4_ATOM_TYPE_COVR, + AP4_ATOM_TYPE_DESC, + AP4_ATOM_TYPE_GNRE, + AP4_ATOM_TYPE_CPIL, + AP4_ATOM_TYPE_TMPO, + AP4_ATOM_TYPE_RTNG, + AP4_ATOM_TYPE_apID, + AP4_ATOM_TYPE_cnID, + AP4_ATOM_TYPE_cmID, + AP4_ATOM_TYPE_atID, + AP4_ATOM_TYPE_plID, + AP4_ATOM_TYPE_geID, + AP4_ATOM_TYPE_sfID, + AP4_ATOM_TYPE_akID, + AP4_ATOM_TYPE_aART, + AP4_ATOM_TYPE_TVNN, + AP4_ATOM_TYPE_TVSH, + AP4_ATOM_TYPE_TVEN, + AP4_ATOM_TYPE_TVSN, + AP4_ATOM_TYPE_TVES, + AP4_ATOM_TYPE_STIK, + AP4_ATOM_TYPE_PGAP, + AP4_ATOM_TYPE_PCST, + AP4_ATOM_TYPE_PURD, + AP4_ATOM_TYPE_PURL, + AP4_ATOM_TYPE_EGID, + AP4_ATOM_TYPE_SONM, + AP4_ATOM_TYPE_SOAL, + AP4_ATOM_TYPE_SOAR, + AP4_ATOM_TYPE_SOAA, + AP4_ATOM_TYPE_SOCO, + AP4_ATOM_TYPE_SOSN +}; +const AP4_MetaDataAtomTypeHandler::TypeList AP4_MetaDataAtomTypeHandler::IlstTypeList = { + IlstTypes, + sizeof(IlstTypes)/sizeof(IlstTypes[0]) +}; + +/*---------------------------------------------------------------------- +| AP4_MetaDataAtomTypeHandler::CreateAtom ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaDataAtomTypeHandler::CreateAtom(AP4_Atom::Type type, + AP4_UI32 size, + AP4_ByteStream& stream, + AP4_Atom::Type context, + AP4_Atom*& atom) +{ + atom = NULL; + + if (context == AP4_ATOM_TYPE_ILST) { + if (IsTypeInList(type, IlstTypeList)) { + m_AtomFactory->PushContext(type); + atom = AP4_ContainerAtom::Create(type, size, false, false, stream, *m_AtomFactory); + m_AtomFactory->PopContext(); + } + } else if (type == AP4_ATOM_TYPE_DATA) { + if (IsTypeInList(context, IlstTypeList)) { + atom = new AP4_DataAtom(size, stream); + } + } else if (context == AP4_ATOM_TYPE_dddd) { + if (type == AP4_ATOM_TYPE_MEAN || type == AP4_ATOM_TYPE_NAME) { + atom = new AP4_MetaDataStringAtom(type, size, stream); + } + } else if (context == AP4_ATOM_TYPE_UDTA) { + if (IsTypeInList(type, _3gppLocalizedStringTypeList)) { + atom = AP4_3GppLocalizedStringAtom::Create(type, size, stream); + } else if (IsTypeInList(type, DcfStringTypeList)) { + atom = AP4_DcfStringAtom::Create(type, size, stream); + } else if (type == AP4_ATOM_TYPE_DCFD) { + atom = AP4_DcfdAtom::Create(size, stream); + } + } + + return atom?AP4_SUCCESS:AP4_FAILURE; +} + +/*---------------------------------------------------------------------- +| AP4_MetaDataAtomTypeHandler::IsTypeInList ++---------------------------------------------------------------------*/ +bool +AP4_MetaDataAtomTypeHandler::IsTypeInList(AP4_Atom::Type type, const AP4_MetaDataAtomTypeHandler::TypeList& list) +{ + for (unsigned int i=0; i<list.m_Size; i++) { + if (type == list.m_Types[i]) return true; + } + return false; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::AP4_MetaData ++---------------------------------------------------------------------*/ +AP4_MetaData::AP4_MetaData(AP4_File* file) +{ + // get the file's movie + AP4_Movie* movie = file->GetMovie(); + + // handle the movie's metadata if there is a movie in the file + if (movie) { + AP4_MoovAtom* moov = movie->GetMoovAtom(); + if (moov == NULL) return; + ParseMoov(moov); + } else { + // if we don't have a movie, try to show metadata from a udta atom + AP4_List<AP4_Atom>& top_level_atoms = file->GetTopLevelAtoms(); + + AP4_List<AP4_Atom>::Item* atom_item = top_level_atoms.FirstItem(); + while (atom_item) { + AP4_ContainerAtom* container = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom_item->GetData()); + if (container) { + // look for a udta in a DCF layout + AP4_Atom* udta = container->FindChild("odhe/udta"); + if (udta) { + AP4_ContainerAtom* udta_container = AP4_DYNAMIC_CAST(AP4_ContainerAtom, udta); + if (udta_container) { + ParseUdta(udta_container, "dcf"); + } + } + } + atom_item = atom_item->GetNext(); + } + } +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::ParseMoov ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::ParseMoov(AP4_MoovAtom* moov) +{ + // look for a 'meta' atom with 'hdlr' type 'mdir' + AP4_HdlrAtom* hdlr = AP4_DYNAMIC_CAST(AP4_HdlrAtom, moov->FindChild("udta/meta/hdlr")); + if (hdlr == NULL || hdlr->GetHandlerType() != AP4_HANDLER_TYPE_MDIR) return AP4_ERROR_NO_SUCH_ITEM; + + // get the list of entries + AP4_ContainerAtom* ilst = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moov->FindChild("udta/meta/ilst")); + if (ilst == NULL) return AP4_ERROR_NO_SUCH_ITEM; + + AP4_List<AP4_Atom>::Item* ilst_item = ilst->GetChildren().FirstItem(); + while (ilst_item) { + AP4_ContainerAtom* entry_atom = AP4_DYNAMIC_CAST(AP4_ContainerAtom, ilst_item->GetData()); + if (entry_atom) { + AddIlstEntries(entry_atom, "meta"); + } + ilst_item = ilst_item->GetNext(); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::ParseUdta ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::ParseUdta(AP4_ContainerAtom* udta, const char* namespc) +{ + // check that the atom is indeed a 'udta' atom + if (udta->GetType() != AP4_ATOM_TYPE_UDTA) { + return AP4_ERROR_INVALID_PARAMETERS; + } + + AP4_List<AP4_Atom>::Item* udta_item = udta->GetChildren().FirstItem(); + for (; udta_item; udta_item = udta_item->GetNext()) { + AP4_3GppLocalizedStringAtom* _3gpp_atom = AP4_DYNAMIC_CAST(AP4_3GppLocalizedStringAtom, udta_item->GetData()); + if (_3gpp_atom) { + Add3GppEntry(_3gpp_atom, namespc); + continue; + } + + AP4_DcfStringAtom* dcfs_atom = AP4_DYNAMIC_CAST(AP4_DcfStringAtom, udta_item->GetData()); + if (dcfs_atom) { + AddDcfStringEntry(dcfs_atom, namespc); + continue; + } + + AP4_DcfdAtom* dcfd_atom = AP4_DYNAMIC_CAST(AP4_DcfdAtom, udta_item->GetData()); + if (dcfd_atom) { + AddDcfdEntry(dcfd_atom, namespc); + } + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::~AP4_MetaData ++---------------------------------------------------------------------*/ +AP4_MetaData::~AP4_MetaData() +{ + m_Entries.DeleteReferences(); +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::ResolveKeyName ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::ResolveKeyName(AP4_Atom::Type atom_type, AP4_String& value) +{ + const char* key_name = NULL; + char four_cc[5]; + + // look for a match in the key infos + for (unsigned int i=0; + i<sizeof(AP4_MetaData_KeyInfos)/sizeof(AP4_MetaData_KeyInfos[0]); + i++) { + if (AP4_MetaData_KeyInfos[i].four_cc == atom_type) { + key_name = AP4_MetaData_KeyInfos[i].name; + break; + } + } + if (key_name == NULL) { + // this key was not found in the key infos, create a name for it + AP4_FormatFourChars(four_cc, (AP4_UI32)atom_type); + key_name = four_cc; + } + value = key_name; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::AddIlstEntries ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::AddIlstEntries(AP4_ContainerAtom* atom, const char* namespc) +{ + AP4_MetaData::Value* value = NULL; + + if (atom->GetType() == AP4_ATOM_TYPE_dddd) { + // look for the namespace + AP4_MetaDataStringAtom* mean = static_cast<AP4_MetaDataStringAtom*>(atom->GetChild(AP4_ATOM_TYPE_MEAN)); + if (mean == NULL) return AP4_ERROR_INVALID_FORMAT; + + // look for the name + AP4_MetaDataStringAtom* name = static_cast<AP4_MetaDataStringAtom*>(atom->GetChild(AP4_ATOM_TYPE_NAME)); + if (name == NULL) return AP4_ERROR_INVALID_FORMAT; + + // get the value + AP4_DataAtom* data_atom = static_cast<AP4_DataAtom*>(atom->GetChild(AP4_ATOM_TYPE_DATA)); + value = new AP4_AtomMetaDataValue(data_atom, atom->GetType()); + if (value == NULL) return AP4_ERROR_INVALID_FORMAT; + + return m_Entries.Add(new Entry(name->GetValue().GetChars(), + mean->GetValue().GetChars(), + value)); + } else { + const char* key_name = NULL; + char four_cc[5]; + + // convert the atom type to a name + AP4_FormatFourChars(four_cc, (AP4_UI32)atom->GetType()); + key_name = four_cc; + + // add one entry for each data atom + AP4_List<AP4_Atom>::Item* data_item = atom->GetChildren().FirstItem(); + while (data_item) { + AP4_Atom* item_atom = data_item->GetData(); + if (item_atom->GetType() == AP4_ATOM_TYPE_DATA) { + AP4_DataAtom* data_atom = static_cast<AP4_DataAtom*>(item_atom); + value = new AP4_AtomMetaDataValue(data_atom, atom->GetType()); + m_Entries.Add(new Entry(key_name, namespc, value)); + } + data_item = data_item->GetNext(); + } + + return AP4_SUCCESS; + } +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Add3GppEntry ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::Add3GppEntry(AP4_3GppLocalizedStringAtom* atom, const char* namespc) +{ + AP4_String key_name; + ResolveKeyName(atom->GetType(), key_name); + + const char* language = NULL; + if (atom->GetLanguage()[0]) { + language = atom->GetLanguage(); + } + AP4_MetaData::Value* value = new AP4_StringMetaDataValue(atom->GetValue().GetChars(), + language); + m_Entries.Add(new Entry(key_name.GetChars(), namespc, value)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::AddDcfStringEntry ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::AddDcfStringEntry(AP4_DcfStringAtom* atom, const char* namespc) +{ + AP4_String key_name; + ResolveKeyName(atom->GetType(), key_name); + + AP4_MetaData::Value* value = new AP4_StringMetaDataValue(atom->GetValue().GetChars()); + m_Entries.Add(new Entry(key_name.GetChars(), namespc, value)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::AddDcfdEntry ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::AddDcfdEntry(AP4_DcfdAtom* atom, const char* namespc) +{ + AP4_String key_name; + ResolveKeyName(atom->GetType(), key_name); + + AP4_MetaData::Value* value = new AP4_IntegerMetaDataValue(AP4_MetaData::Value::TYPE_INT_32_BE, + atom->GetDuration()); + m_Entries.Add(new Entry(key_name.GetChars(), namespc, value)); + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Value::MapDataTypeToCategory ++---------------------------------------------------------------------*/ +AP4_MetaData::Value::TypeCategory +AP4_MetaData::Value::MapTypeToCategory(Type type) +{ + switch (type) { + case AP4_MetaData::Value::TYPE_INT_08_BE: + case AP4_MetaData::Value::TYPE_INT_16_BE: + case AP4_MetaData::Value::TYPE_INT_32_BE: + return AP4_MetaData::Value::TYPE_CATEGORY_INTEGER; + + case AP4_MetaData::Value::TYPE_STRING_UTF_8: + case AP4_MetaData::Value::TYPE_STRING_UTF_16: + case AP4_MetaData::Value::TYPE_STRING_PASCAL: + return AP4_MetaData::Value::TYPE_CATEGORY_STRING; + + case AP4_MetaData::Value::TYPE_FLOAT_32_BE: + case AP4_MetaData::Value::TYPE_FLOAT_64_BE: + return AP4_MetaData::Value::TYPE_CATEGORY_FLOAT; + + default: + return AP4_MetaData::Value::TYPE_CATEGORY_BINARY; + } +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Value::GetTypeCategory ++---------------------------------------------------------------------*/ +AP4_MetaData::Value::TypeCategory +AP4_MetaData::Value::GetTypeCategory() const +{ + return MapTypeToCategory(m_Type); +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Entry::ToAtom ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::Entry::ToAtom(AP4_Atom*& atom) const +{ + atom = NULL; + + if (m_Value == NULL) { + return AP4_ERROR_INVALID_PARAMETERS; + } + + if (m_Key.GetNamespace() == "meta") { + // convert the name into an atom type + if (m_Key.GetName().GetLength() != 4) { + // the name is not in the right format + return AP4_ERROR_INVALID_PARAMETERS; + } + AP4_Atom::Type atom_type = AP4_Atom::TypeFromString(m_Key.GetName().GetChars()); + + // create a container atom for the data + AP4_ContainerAtom* container = new AP4_ContainerAtom(atom_type); + + // add the data atom + AP4_DataAtom* data = new AP4_DataAtom(*m_Value); + container->AddChild(data); + + atom = container; + return AP4_SUCCESS; + } else if (m_Key.GetNamespace() == "dcf") { + // convert the name into an atom type + if (m_Key.GetName().GetLength() != 4) { + // the name is not in the right format + return AP4_ERROR_INVALID_PARAMETERS; + } + AP4_Atom::Type atom_type = AP4_Atom::TypeFromString(m_Key.GetName().GetChars()); + + if (AP4_MetaDataAtomTypeHandler::IsTypeInList(atom_type, + AP4_MetaDataAtomTypeHandler::DcfStringTypeList)) { + AP4_String atom_value = m_Value->ToString(); + atom = new AP4_DcfStringAtom(atom_type, atom_value.GetChars()); + return AP4_SUCCESS; + } else if (AP4_MetaDataAtomTypeHandler::IsTypeInList(atom_type, + AP4_MetaDataAtomTypeHandler::_3gppLocalizedStringTypeList)) { + AP4_String atom_value = m_Value->ToString(); + const char* language = "eng"; // default + if (m_Value->GetLanguage().GetLength() != 0) { + language = m_Value->GetLanguage().GetChars(); + } + atom = new AP4_3GppLocalizedStringAtom(atom_type, language, atom_value.GetChars()); + return AP4_SUCCESS; + } else if (atom_type == AP4_ATOM_TYPE_DCFD) { + atom = new AP4_DcfdAtom(m_Value->ToInteger()); + return AP4_SUCCESS; + } + + // not supported + return AP4_ERROR_NOT_SUPPORTED; + } else { + // create a '----' atom + AP4_ContainerAtom* container = new AP4_ContainerAtom(AP4_ATOM_TYPE_dddd); + + // add a 'mean' string + container->AddChild(new AP4_MetaDataStringAtom(AP4_ATOM_TYPE_MEAN, m_Key.GetNamespace().GetChars())); + + // add a 'name' string + container->AddChild(new AP4_MetaDataStringAtom(AP4_ATOM_TYPE_NAME, m_Key.GetName().GetChars())); + + // add the data atom + AP4_DataAtom* data = new AP4_DataAtom(*m_Value); + container->AddChild(data); + + atom = container; + return AP4_SUCCESS; + } + + return AP4_ERROR_NOT_SUPPORTED; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Entry::FindInIlst ++---------------------------------------------------------------------*/ +AP4_ContainerAtom* +AP4_MetaData::Entry::FindInIlst(AP4_ContainerAtom* ilst) const +{ + if (m_Key.GetNamespace() == "meta") { + AP4_Atom::Type atom_type = AP4_Atom::TypeFromString(m_Key.GetName().GetChars()); + return AP4_DYNAMIC_CAST(AP4_ContainerAtom, ilst->GetChild(atom_type)); + } else { + AP4_List<AP4_Atom>::Item* ilst_item = ilst->GetChildren().FirstItem(); + while (ilst_item) { + AP4_ContainerAtom* entry_atom = AP4_DYNAMIC_CAST(AP4_ContainerAtom, ilst_item->GetData()); + if (entry_atom) { + AP4_MetaDataStringAtom* mean = static_cast<AP4_MetaDataStringAtom*>(entry_atom->GetChild(AP4_ATOM_TYPE_MEAN)); + AP4_MetaDataStringAtom* name = static_cast<AP4_MetaDataStringAtom*>(entry_atom->GetChild(AP4_ATOM_TYPE_NAME)); + if (mean && name && + mean->GetValue() == m_Key.GetNamespace() && + name->GetValue() == m_Key.GetName()) { + return entry_atom; + } + } + ilst_item = ilst_item->GetNext(); + } + } + + // not found + return NULL; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Entry::AddToFileIlst ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::Entry::AddToFileIlst(AP4_File& file, AP4_Ordinal index) +{ + // check that we have a correct entry + if (m_Value == NULL) return AP4_ERROR_INVALID_STATE; + + // convert the entry into an atom + AP4_Atom* atom; + AP4_Result result = ToAtom(atom); + if (AP4_FAILED(result)) return result; + AP4_ContainerAtom* entry_atom = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom); + if (entry_atom == NULL) { + return AP4_ERROR_INVALID_FORMAT; + } + + // look for the 'moov' + AP4_Movie* movie = file.GetMovie(); + if (movie == NULL) return AP4_ERROR_INVALID_FORMAT; + AP4_MoovAtom* moov = movie->GetMoovAtom(); + if (moov == NULL) return AP4_ERROR_INVALID_FORMAT; + + // look for 'udta', and create if it does not exist + AP4_ContainerAtom* udta = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moov->FindChild("udta", true)); + if (udta == NULL) return AP4_ERROR_INTERNAL; + + // look for 'meta', and create if it does not exist ('meta' is a FULL atom) + AP4_ContainerAtom* meta = AP4_DYNAMIC_CAST(AP4_ContainerAtom, udta->FindChild("meta", true, true)); + if (meta == NULL) return AP4_ERROR_INTERNAL; + + // look for a 'hdlr' atom type 'mdir' + AP4_HdlrAtom* hdlr = AP4_DYNAMIC_CAST(AP4_HdlrAtom, meta->FindChild("hdlr")); + if (hdlr == NULL) { + hdlr = new AP4_HdlrAtom(AP4_HANDLER_TYPE_MDIR, ""); + meta->AddChild(hdlr); + } else { + if (hdlr->GetHandlerType() != AP4_HANDLER_TYPE_MDIR) { + return AP4_ERROR_INVALID_FORMAT; + } + } + + // get/create the list of entries + AP4_ContainerAtom* ilst = AP4_DYNAMIC_CAST(AP4_ContainerAtom, meta->FindChild("ilst", true)); + if (ilst == NULL) return AP4_ERROR_INTERNAL; + + // look if there is already a container for this entry + AP4_ContainerAtom* existing = FindInIlst(ilst); + if (existing == NULL) { + // just add the one we have + ilst->AddChild(entry_atom); + } else { + // add the entry's data to the existing entry + AP4_DataAtom* data_atom = AP4_DYNAMIC_CAST(AP4_DataAtom, entry_atom->GetChild(AP4_ATOM_TYPE_DATA)); + if (data_atom == NULL) return AP4_ERROR_INTERNAL; + entry_atom->RemoveChild(data_atom); + existing->AddChild(data_atom, index); + delete entry_atom; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Entry::AddToFileDcf ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::Entry::AddToFileDcf(AP4_File& file, AP4_Ordinal index) +{ + // check that we have a correct entry + if (m_Value == NULL) return AP4_ERROR_INVALID_STATE; + + // look for 'odrm/odhe' + AP4_ContainerAtom* odhe = AP4_DYNAMIC_CAST(AP4_ContainerAtom, file.FindChild("odrm/odhe")); + if (odhe == NULL) return AP4_ERROR_NO_SUCH_ITEM; + + // get/create the list of entries + AP4_ContainerAtom* udta = AP4_DYNAMIC_CAST(AP4_ContainerAtom, odhe->FindChild("udta", true)); + if (udta == NULL) return AP4_ERROR_INTERNAL; + + // convert the entry into an atom + AP4_Atom* data_atom; + AP4_Result result = ToAtom(data_atom); + if (AP4_FAILED(result)) return result; + + // add the entry's data to the container + return udta->AddChild(data_atom, index); +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Entry::AddToFile ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::Entry::AddToFile(AP4_File& file, AP4_Ordinal index) +{ + // check that we have a correct entry + if (m_Value == NULL) return AP4_ERROR_INVALID_STATE; + + // check the namespace of the key to know where to add the atom + if (m_Key.GetNamespace() == "meta") { + return AddToFileIlst(file, index); + } else if (m_Key.GetNamespace() == "dcf") { + return AddToFileDcf(file, index); + } else { + // unsupported namespace + return AP4_ERROR_NOT_SUPPORTED; + } +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Entry::RemoveFromFileIlst ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::Entry::RemoveFromFileIlst(AP4_File& file, AP4_Ordinal index) +{ + // look for the 'moov' + AP4_Movie* movie = file.GetMovie(); + if (movie == NULL) return AP4_ERROR_INVALID_FORMAT; + AP4_MoovAtom* moov = movie->GetMoovAtom(); + if (moov == NULL) return AP4_ERROR_INVALID_FORMAT; + + // look for 'udta/meta/ilst' + AP4_ContainerAtom* ilst = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moov->FindChild("udta/meta/ilst")); + if (ilst == NULL) return AP4_ERROR_NO_SUCH_ITEM; + + // look if there is already a container for this entry + AP4_ContainerAtom* existing = FindInIlst(ilst); + if (existing == NULL) return AP4_ERROR_NO_SUCH_ITEM; + + // remove the data atom in the entry + AP4_Result result = existing->DeleteChild(AP4_ATOM_TYPE_DATA, index); + if (AP4_FAILED(result)) return result; + + // if the entry is empty, remove it + if (existing->GetChildren().ItemCount() == 0) { + ilst->RemoveChild(existing); + delete existing; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Entry::RemoveFromFileDcf ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::Entry::RemoveFromFileDcf(AP4_File& file, AP4_Ordinal index) +{ + // look for 'odrm/odhe/udta' + AP4_ContainerAtom* udta = AP4_DYNAMIC_CAST(AP4_ContainerAtom, file.FindChild("odrm/odhe/udta")); + if (udta == NULL) return AP4_ERROR_NO_SUCH_ITEM; + + // remove the data atom in the entry + AP4_UI32 type = AP4_BytesToUInt32BE((const unsigned char*)m_Key.GetName().GetChars()); + AP4_Result result = udta->DeleteChild(type, index); + if (AP4_FAILED(result)) return result; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_MetaData::Entry::RemoveFromFile ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaData::Entry::RemoveFromFile(AP4_File& file, AP4_Ordinal index) +{ + // check the namespace of the key to know where to add the atom + if (m_Key.GetNamespace() == "meta") { + return RemoveFromFileIlst(file, index); + } else if (m_Key.GetNamespace() == "dcf") { + return RemoveFromFileDcf(file, index); + } else { + // unsupported namespace + return AP4_ERROR_NOT_SUPPORTED; + } +} + +/*---------------------------------------------------------------------- +| AP4_StringMetaDataValue::ToString ++---------------------------------------------------------------------*/ +AP4_String +AP4_StringMetaDataValue::ToString() const +{ + return m_Value; +} + +/*---------------------------------------------------------------------- +| AP4_StringMetaDataValue::ToBytes ++---------------------------------------------------------------------*/ +AP4_Result +AP4_StringMetaDataValue::ToBytes(AP4_DataBuffer& /* bytes */) const +{ + return AP4_ERROR_NOT_SUPPORTED; +} + +/*---------------------------------------------------------------------- +| AP4_StringMetaDataValue::ToInteger ++---------------------------------------------------------------------*/ +long +AP4_StringMetaDataValue::ToInteger() const +{ + return 0; +} + +/*---------------------------------------------------------------------- +| AP4_IntegerMetaDataValue::ToString ++---------------------------------------------------------------------*/ +AP4_String +AP4_IntegerMetaDataValue::ToString() const +{ + char value[16]; + AP4_FormatString(value, sizeof(value), "%ld", m_Value); + return AP4_String(value); +} + +/*---------------------------------------------------------------------- +| AP4_IntegerMetaDataValue::ToBytes ++---------------------------------------------------------------------*/ +AP4_Result +AP4_IntegerMetaDataValue::ToBytes(AP4_DataBuffer& /* bytes */) const +{ + return AP4_ERROR_NOT_SUPPORTED; +} + +/*---------------------------------------------------------------------- +| AP4_IntegerMetaDataValue::ToInteger ++---------------------------------------------------------------------*/ +long +AP4_IntegerMetaDataValue::ToInteger() const +{ + return m_Value; +} + +/*---------------------------------------------------------------------- +| AP4_BinaryMetaDataValue::ToString ++---------------------------------------------------------------------*/ +AP4_String +AP4_BinaryMetaDataValue::ToString() const +{ + return AP4_String(); // not supported +} + +/*---------------------------------------------------------------------- +| AP4_BinaryMetaDataValue::ToBytes ++---------------------------------------------------------------------*/ +AP4_Result +AP4_BinaryMetaDataValue::ToBytes(AP4_DataBuffer& bytes) const +{ + bytes.SetDataSize(m_Value.GetDataSize()); + AP4_CopyMemory(bytes.UseData(), m_Value.GetData(), m_Value.GetDataSize()); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_BinaryMetaDataValue::ToInteger ++---------------------------------------------------------------------*/ +long +AP4_BinaryMetaDataValue::ToInteger() const +{ + return 0; // NOT SUPPORTED +} + +/*---------------------------------------------------------------------- +| AP4_AtomMetaDataValue::AP4_AtomMetaDataValue ++---------------------------------------------------------------------*/ +AP4_AtomMetaDataValue::AP4_AtomMetaDataValue(AP4_DataAtom* atom, + AP4_UI32 parent_type) : + Value(atom->GetValueType()), + m_DataAtom(atom) +{ + switch (parent_type) { + case AP4_ATOM_TYPE_GNRE: + m_Meaning = MEANING_ID3_GENRE; + break; + + case AP4_ATOM_TYPE_CPIL: + m_Meaning = MEANING_BOOLEAN; + break; + + case AP4_ATOM_TYPE_PGAP: + case AP4_ATOM_TYPE_PCST: + m_Meaning = MEANING_BOOLEAN; + break; + + case AP4_ATOM_TYPE_STIK: + m_Meaning = MEANING_FILE_KIND; + break; + + case AP4_ATOM_TYPE_PURL: + case AP4_ATOM_TYPE_EGID: + m_Meaning = MEANING_BINARY_ENCODED_CHARS; + break; + + default: + break; + } +} + +/*---------------------------------------------------------------------- +| AP4_AtomMetaDataValue::ToString ++---------------------------------------------------------------------*/ +AP4_String +AP4_AtomMetaDataValue::ToString() const +{ + char string[256] = ""; + + AP4_MetaData::Value::Type value_type = m_DataAtom->GetValueType(); + switch (AP4_MetaData::Value::MapTypeToCategory(value_type)) { + case AP4_MetaData::Value::TYPE_CATEGORY_INTEGER: + { + long value; + if (AP4_SUCCEEDED(m_DataAtom->LoadInteger(value))) { + if (m_Meaning == MEANING_BOOLEAN) { + if (value) { + return "True"; + } else { + return "False"; + } + } else if (m_Meaning == MEANING_FILE_KIND) { + if (value >= 0 && ((unsigned int)value) <= sizeof(Ap4StikNames)/sizeof(Ap4StikNames[0])) { + AP4_FormatString(string, sizeof(string), "(%ld) %s", value, Ap4StikNames[value]); + } else { + return "Unknown"; + } + } else { + AP4_FormatString(string, sizeof(string), "%ld", value); + } + } + return AP4_String((const char*)string); + break; + } + + case AP4_MetaData::Value::TYPE_CATEGORY_STRING: + { + AP4_String* category_string; + if (AP4_SUCCEEDED(m_DataAtom->LoadString(category_string))) { + AP4_String result(*category_string); + delete category_string; + return result; + } + break; + } + + case AP4_MetaData::Value::TYPE_CATEGORY_BINARY: + { + AP4_DataBuffer data; + if (AP4_SUCCEEDED(m_DataAtom->LoadBytes(data))) { + if (m_Meaning == MEANING_ID3_GENRE && data.GetDataSize() == 2) { + unsigned int genre = (data.GetData()[0])*256+data.GetData()[1]; + if (genre >= 1 && genre <= sizeof(Ap4Id3Genres)/sizeof(Ap4Id3Genres[0])) { + AP4_FormatString(string, sizeof(string), "(%d) %s", genre, Ap4Id3Genres[genre-1]); + return AP4_String((const char*)string); + } else { + return "Unknown"; + } + } else if (m_Meaning == MEANING_BINARY_ENCODED_CHARS) { + AP4_String result; + result.Assign((const char*)data.GetData(), data.GetDataSize()); + return result; + } else { + unsigned int dump_length = data.GetDataSize(); + bool truncate = false; + if (dump_length > 16) { + dump_length = 16; + truncate = true; + } + char* out = string; + for (unsigned int i=0; i<dump_length; i++) { + AP4_FormatString(out, sizeof(string)-(out-string), "%02x ", data.GetData()[i]); + out += 3; + } + if (truncate) { + *out++='.'; *out++='.'; *out++='.'; *out++=' '; + } + AP4_FormatString(out, sizeof(string)-(out-string), "[%ld bytes]", data.GetDataSize()); + } + } + return AP4_String(string); + } + default: + return AP4_String(); + } + + return AP4_String(); +} + +/*---------------------------------------------------------------------- +| AP4_AtomMetaDataValue::ToBytes ++---------------------------------------------------------------------*/ +AP4_Result +AP4_AtomMetaDataValue::ToBytes(AP4_DataBuffer& bytes) const +{ + return m_DataAtom->LoadBytes(bytes); +} + +/*---------------------------------------------------------------------- +| AP4_AtomMetaDataValue::ToInteger ++---------------------------------------------------------------------*/ +long +AP4_AtomMetaDataValue::ToInteger() const +{ + long value; + if (AP4_SUCCEEDED(m_DataAtom->LoadInteger(value))) { + return value; + } else { + return 0; + } +} + +/*---------------------------------------------------------------------- +| AP4_DataAtom::AP4_DataAtom ++---------------------------------------------------------------------*/ +AP4_DataAtom::AP4_DataAtom(const AP4_MetaData::Value& value) : + AP4_Atom(AP4_ATOM_TYPE_DATA, AP4_ATOM_HEADER_SIZE), + m_DataType(DATA_TYPE_BINARY) +{ + AP4_MemoryByteStream* memory = new AP4_MemoryByteStream(256); + AP4_Size payload_size = 8; + m_Source = memory; + + switch (value.GetType()) { + case AP4_MetaData::Value::TYPE_STRING_UTF_8: { + m_DataType = DATA_TYPE_STRING_UTF_8; + AP4_String string_value = value.ToString(); + if (string_value.GetLength()) { + memory->Write(string_value.GetChars(), string_value.GetLength()); + } + payload_size += string_value.GetLength(); + break; + } + + case AP4_MetaData::Value::TYPE_INT_08_BE: { + m_DataType = DATA_TYPE_SIGNED_INT_BE; + AP4_UI08 int_value = (AP4_UI08)value.ToInteger(); + memory->Write(&int_value, 1); + payload_size += 1; + break; + } + + case AP4_MetaData::Value::TYPE_INT_16_BE: { + m_DataType = DATA_TYPE_SIGNED_INT_BE; + AP4_UI16 int_value = (AP4_UI16)value.ToInteger(); + memory->Write(&int_value, 2); + payload_size += 2; + break; + } + + case AP4_MetaData::Value::TYPE_INT_32_BE: { + m_DataType = DATA_TYPE_SIGNED_INT_BE; + AP4_UI32 int_value = (AP4_UI32)value.ToInteger(); + memory->Write(&int_value, 4); + payload_size += 4; + break; + } + + case AP4_MetaData::Value::TYPE_JPEG: + m_DataType = DATA_TYPE_JPEG; + // FALLTHROUGH + case AP4_MetaData::Value::TYPE_GIF: + if (m_DataType == DATA_TYPE_BINARY) m_DataType = DATA_TYPE_GIF; + // FALLTHROUGH + case AP4_MetaData::Value::TYPE_BINARY: { + AP4_DataBuffer buffer; + value.ToBytes(buffer); + if (buffer.GetDataSize()) { + memory->Write(buffer.GetData(), buffer.GetDataSize()); + } + payload_size += buffer.GetDataSize(); + break; + } + + default: + break; + } + + const AP4_String& language = value.GetLanguage(); + if (language == "en") { + m_DataLang = LANGUAGE_ENGLISH; + } else { + // default + m_DataLang = LANGUAGE_ENGLISH; + } + + m_Size32 += payload_size; +} + +/*---------------------------------------------------------------------- +| AP4_DataAtom::AP4_DataAtom ++---------------------------------------------------------------------*/ +AP4_DataAtom::AP4_DataAtom(AP4_UI32 size, AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_DATA, size) +{ + if (size < AP4_ATOM_HEADER_SIZE+8) return; + + AP4_UI32 i; + stream.ReadUI32(i); m_DataType = (DataType)i; + stream.ReadUI32(i); m_DataLang = (DataLang)i; + + // the stream for the data is a substream of this source + AP4_Position data_offset; + stream.Tell(data_offset); + AP4_Size data_size = size-AP4_ATOM_HEADER_SIZE-8; + m_Source = new AP4_SubStream(stream, data_offset, data_size); +} + +/*---------------------------------------------------------------------- +| AP4_DataAtom::~AP4_DataAtom ++---------------------------------------------------------------------*/ +AP4_DataAtom::~AP4_DataAtom() +{ + delete(m_Source); +} + +/*---------------------------------------------------------------------- +| AP4_DataAtom::GetValueType ++---------------------------------------------------------------------*/ +AP4_MetaData::Value::Type +AP4_DataAtom::GetValueType() +{ + switch (m_DataType) { + case DATA_TYPE_BINARY: + return AP4_MetaData::Value::TYPE_BINARY; + + case DATA_TYPE_SIGNED_INT_BE: + switch (m_Size32-16) { + case 1: return AP4_MetaData::Value::TYPE_INT_08_BE; + case 2: return AP4_MetaData::Value::TYPE_INT_16_BE; + case 4: return AP4_MetaData::Value::TYPE_INT_32_BE; + default: return AP4_MetaData::Value::TYPE_BINARY; + } + break; + + case DATA_TYPE_STRING_UTF_8: + return AP4_MetaData::Value::TYPE_STRING_UTF_8; + + case DATA_TYPE_STRING_UTF_16: + return AP4_MetaData::Value::TYPE_STRING_UTF_16; + + case DATA_TYPE_STRING_PASCAL: + return AP4_MetaData::Value::TYPE_STRING_PASCAL; + + case DATA_TYPE_GIF: + return AP4_MetaData::Value::TYPE_GIF; + + case DATA_TYPE_JPEG: + return AP4_MetaData::Value::TYPE_JPEG; + + default: + return AP4_MetaData::Value::TYPE_BINARY; + } + + return AP4_MetaData::Value::TYPE_BINARY; +} + +/*---------------------------------------------------------------------- +| AP4_DataAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DataAtom::WriteFields(AP4_ByteStream& stream) +{ + stream.WriteUI32(m_DataType); + stream.WriteUI32(m_DataLang); + if (m_Source) { + AP4_LargeSize size = 0; + m_Source->GetSize(size); + m_Source->Seek(0); + m_Source->CopyTo(stream, size); + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DataAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DataAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("type", m_DataType); + inspector.AddField("lang", m_DataLang); + if (m_DataType == DATA_TYPE_STRING_UTF_8) { + AP4_String* str; + if (AP4_SUCCEEDED(LoadString(str))) { + inspector.AddField("value", str->GetChars()); + delete str; + } + } else if (m_DataType == DATA_TYPE_SIGNED_INT_BE) { + long value; + if (AP4_SUCCEEDED(LoadInteger(value))) { + inspector.AddField("value", value); + } + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DataAtom::LoadString ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DataAtom::LoadString(AP4_String*& string) +{ + if (m_Source == NULL) { + string = new AP4_String(); + return AP4_SUCCESS; + } else { + // create a string with enough capactiy for the data + AP4_LargeSize size = 0; + m_Source->GetSize(size); + if (size > AP4_DATA_ATOM_MAX_SIZE) return AP4_ERROR_OUT_OF_RANGE; + string = new AP4_String((AP4_Size)size); + + // read from the start of the stream + m_Source->Seek(0); + AP4_Result result = m_Source->Read(string->UseChars(), (AP4_Size)size); + if (AP4_FAILED(result)) { + delete string; + string = NULL; + } + + return result; + } +} + +/*---------------------------------------------------------------------- +| AP4_DataAtom::LoadBytes ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DataAtom::LoadBytes(AP4_DataBuffer& bytes) +{ + if (m_Source == NULL) { + bytes.SetDataSize(0); + return AP4_SUCCESS; + } + AP4_LargeSize size = 0; + m_Source->GetSize(size); + if (size > AP4_DATA_ATOM_MAX_SIZE) return AP4_ERROR_OUT_OF_RANGE; + bytes.SetDataSize((AP4_Size)size); + m_Source->Seek(0); + AP4_Result result = m_Source->Read(bytes.UseData(), (AP4_Size)size); + if (AP4_FAILED(result)) { + bytes.SetDataSize(0); + } + return result; +} + +/*---------------------------------------------------------------------- +| AP4_DataAtom::LoadInteger ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DataAtom::LoadInteger(long& value) +{ + AP4_Result result = AP4_FAILURE; + value = 0; + if (m_Source == NULL) return AP4_SUCCESS; + AP4_LargeSize size = 0; + m_Source->GetSize(size); + if (size > 4) { + return AP4_ERROR_OUT_OF_RANGE; + } + unsigned char bytes[4]; + m_Source->Seek(0); + m_Source->Read(bytes, (AP4_Size)size); + result = AP4_SUCCESS; + switch (size) { + case 1: value = bytes[0]; break; + case 2: value = AP4_BytesToInt16BE(bytes); break; + case 4: value = AP4_BytesToInt32BE(bytes); break; + default: value = 0; result = AP4_ERROR_INVALID_FORMAT; break; + } + return result; +} + +/*---------------------------------------------------------------------- +| AP4_MetaDataStringAtom::AP4_MetaDataStringAtom ++---------------------------------------------------------------------*/ +AP4_MetaDataStringAtom::AP4_MetaDataStringAtom(Type type, const char* value) : + AP4_Atom(type, AP4_ATOM_HEADER_SIZE), + m_Value(value) +{ + m_Size32 += 4+m_Value.GetLength(); +} + +/*---------------------------------------------------------------------- +| AP4_MetaDataStringAtom::AP4_MetaDataStringAtom ++---------------------------------------------------------------------*/ +AP4_MetaDataStringAtom::AP4_MetaDataStringAtom(Type type, AP4_UI32 size, AP4_ByteStream& stream) : + AP4_Atom(type, size), + m_Value((AP4_Size)(size-AP4_ATOM_HEADER_SIZE-4)) +{ + stream.ReadUI32(m_Reserved); + stream.Read(m_Value.UseChars(), m_Value.GetLength()); +} + +/*---------------------------------------------------------------------- +| AP4_MetaDataStringAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaDataStringAtom::WriteFields(AP4_ByteStream& stream) +{ + stream.WriteUI32(m_Reserved); + return stream.Write(m_Value.GetChars(), m_Value.GetLength()); +} + +/*---------------------------------------------------------------------- +| AP4_MetaDataStringAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MetaDataStringAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("value", m_Value.GetChars()); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_3GppLocalizedStringAtom::Create ++---------------------------------------------------------------------*/ +AP4_3GppLocalizedStringAtom* +AP4_3GppLocalizedStringAtom::Create(Type type, AP4_UI32 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_3GppLocalizedStringAtom(type, size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_3GppLocalizedStringAtom::AP4_3GppLocalizedStringAtom ++---------------------------------------------------------------------*/ +AP4_3GppLocalizedStringAtom::AP4_3GppLocalizedStringAtom(Type type, + const char* language, + const char* value) : + AP4_Atom(type, AP4_FULL_ATOM_HEADER_SIZE+2, 0, 0), + m_Value(value) +{ + m_Language[0] = language[0]; + m_Language[1] = language[1]; + m_Language[2] = language[2]; + m_Language[3] = language[3]; + + m_Size32 += m_Value.GetLength()+1; +} + +/*---------------------------------------------------------------------- +| AP4_3GppLocalizedStringAtom::AP4_3GppLocalizedStringAtom ++---------------------------------------------------------------------*/ +AP4_3GppLocalizedStringAtom::AP4_3GppLocalizedStringAtom(Type type, + AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(type, size, version, flags) +{ + // read the language code + AP4_UI16 packed_language; + stream.ReadUI16(packed_language); + m_Language[0] = 0x60+((packed_language>>10)&0x1F); + m_Language[1] = 0x60+((packed_language>> 5)&0x1F); + m_Language[2] = 0x60+((packed_language )&0x1F); + m_Language[3] = '\0'; + + // read the value (should be a NULL-terminated string, but we'll + // allow for strings that are not terminated) + if (size > AP4_FULL_ATOM_HEADER_SIZE+2) { + AP4_UI32 value_size = size-(AP4_FULL_ATOM_HEADER_SIZE+2); + char* value = new char[value_size]; + stream.Read(value, value_size); + m_Value.Assign(value, value_size); + delete[] value; + } +} + +/*---------------------------------------------------------------------- +| AP4_3GppLocalizedStringAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_3GppLocalizedStringAtom::WriteFields(AP4_ByteStream& stream) +{ + AP4_UI16 packed_language = ((m_Language[0]-0x60)<<10) | + ((m_Language[1]-0x60)<< 5) | + ((m_Language[2]-0x60)); + stream.WriteUI16(packed_language); + AP4_Size payload_size = (AP4_UI32)GetSize()-GetHeaderSize(); + if (payload_size < 2) return AP4_ERROR_INVALID_FORMAT; + AP4_Size value_size = m_Value.GetLength()+1; + if (value_size > payload_size-2) { + value_size = payload_size-2; + } + stream.Write(m_Value.GetChars(), value_size); + for (unsigned int i=value_size; i<payload_size-2; i++) { + stream.WriteUI08(0); + } + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_3GppLocalizedStringAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_3GppLocalizedStringAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("language", GetLanguage()); + inspector.AddField("value", m_Value.GetChars()); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DcfStringAtom::Create ++---------------------------------------------------------------------*/ +AP4_DcfStringAtom* +AP4_DcfStringAtom::Create(Type type, AP4_UI32 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_DcfStringAtom(type, size, version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_DcfStringAtom::AP4_DcfStringAtom ++---------------------------------------------------------------------*/ +AP4_DcfStringAtom::AP4_DcfStringAtom(Type type, const char* value) : + AP4_Atom(type, AP4_FULL_ATOM_HEADER_SIZE, 0, 0), + m_Value(value) +{ + m_Size32 += m_Value.GetLength(); +} + +/*---------------------------------------------------------------------- +| AP4_DcfStringAtom::AP4_DcfStringAtom ++---------------------------------------------------------------------*/ +AP4_DcfStringAtom::AP4_DcfStringAtom(Type type, + AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(type, size, version, flags) +{ + if (size > AP4_FULL_ATOM_HEADER_SIZE) { + AP4_UI32 value_size = size-(AP4_FULL_ATOM_HEADER_SIZE); + char* value = new char[value_size]; + stream.Read(value, value_size); + m_Value.Assign(value, value_size); + delete[] value; + } +} + +/*---------------------------------------------------------------------- +| AP4_DcfStringAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DcfStringAtom::WriteFields(AP4_ByteStream& stream) +{ + if (m_Value.GetLength()) stream.Write(m_Value.GetChars(), m_Value.GetLength()); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DcfStringAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DcfStringAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("value", m_Value.GetChars()); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DcfdAtom::Create ++---------------------------------------------------------------------*/ +AP4_DcfdAtom* +AP4_DcfdAtom::Create(AP4_UI32 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 != AP4_FULL_ATOM_HEADER_SIZE+4) return NULL; + return new AP4_DcfdAtom(version, flags, stream); +} + +/*---------------------------------------------------------------------- +| AP4_DcfdAtom::AP4_DcfdAtom ++---------------------------------------------------------------------*/ +AP4_DcfdAtom::AP4_DcfdAtom(AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream) : + AP4_Atom(AP4_ATOM_TYPE_DCFD, AP4_FULL_ATOM_HEADER_SIZE+4, version, flags) +{ + stream.ReadUI32(m_Duration); +} + +/*---------------------------------------------------------------------- +| AP4_DcfdAtom::AP4_DcfdAtom ++---------------------------------------------------------------------*/ +AP4_DcfdAtom::AP4_DcfdAtom(AP4_UI32 duration) : + AP4_Atom(AP4_ATOM_TYPE_DCFD, AP4_FULL_ATOM_HEADER_SIZE+4, 0, 0), + m_Duration(duration) +{ +} + +/*---------------------------------------------------------------------- +| AP4_DcfdAtom::WriteFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DcfdAtom::WriteFields(AP4_ByteStream& stream) +{ + stream.WriteUI32(m_Duration); + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_DcfdAtom::InspectFields ++---------------------------------------------------------------------*/ +AP4_Result +AP4_DcfdAtom::InspectFields(AP4_AtomInspector& inspector) +{ + inspector.AddField("duration", m_Duration); + return AP4_SUCCESS; +} diff --git a/src/filters/parser/mp4splitter/AP4/Source/MetaData/Ap4MetaData.h b/src/filters/parser/mp4splitter/AP4/Source/MetaData/Ap4MetaData.h new file mode 100644 index 000000000..491365f11 --- /dev/null +++ b/src/filters/parser/mp4splitter/AP4/Source/MetaData/Ap4MetaData.h @@ -0,0 +1,576 @@ +/***************************************************************** +| +| AP4 - MetaData +| +| 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_META_DATA_H_ +#define _AP4_META_DATA_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Ap4Atom.h" +#include "Ap4AtomFactory.h" +#include "Ap4String.h" +#include "Ap4Array.h" +#include "Ap4List.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class AP4_File; +class AP4_MoovAtom; +class AP4_DataBuffer; +class AP4_ContainerAtom; +class AP4_DataAtom; +class AP4_3GppLocalizedStringAtom; +class AP4_DcfStringAtom; +class AP4_DcfdAtom; + +/*---------------------------------------------------------------------- +| metadata keys ++---------------------------------------------------------------------*/ +const AP4_Atom::Type AP4_ATOM_TYPE_DATA = AP4_ATOM_TYPE('d','a','t','a'); // data +const AP4_Atom::Type AP4_ATOM_TYPE_MEAN = AP4_ATOM_TYPE('m','e','a','n'); // namespace +const AP4_Atom::Type AP4_ATOM_TYPE_NAME = AP4_ATOM_TYPE('n','a','m','e'); // name +const AP4_Atom::Type AP4_ATOM_TYPE_dddd = AP4_ATOM_TYPE('-','-','-','-'); // free form +const AP4_Atom::Type AP4_ATOM_TYPE_cNAM = AP4_ATOM_TYPE(0xA9,'n','a','m'); // name +const AP4_Atom::Type AP4_ATOM_TYPE_cART = AP4_ATOM_TYPE(0xA9,'A','R','T'); // artist +const AP4_Atom::Type AP4_ATOM_TYPE_cCOM = AP4_ATOM_TYPE(0xA9,'c','o','m'); // composer +const AP4_Atom::Type AP4_ATOM_TYPE_cWRT = AP4_ATOM_TYPE(0xA9,'w','r','t'); // writer +const AP4_Atom::Type AP4_ATOM_TYPE_cALB = AP4_ATOM_TYPE(0xA9,'a','l','b'); // album +const AP4_Atom::Type AP4_ATOM_TYPE_cGEN = AP4_ATOM_TYPE(0xA9,'g','e','n'); // genre +const AP4_Atom::Type AP4_ATOM_TYPE_cGRP = AP4_ATOM_TYPE(0xA9,'g','r','p'); // group +const AP4_Atom::Type AP4_ATOM_TYPE_cDAY = AP4_ATOM_TYPE(0xA9,'d','a','y'); // date +const AP4_Atom::Type AP4_ATOM_TYPE_cTOO = AP4_ATOM_TYPE(0xA9,'t','o','o'); // tool +const AP4_Atom::Type AP4_ATOM_TYPE_cCMT = AP4_ATOM_TYPE(0xA9,'c','m','t'); // comment +const AP4_Atom::Type AP4_ATOM_TYPE_cLYR = AP4_ATOM_TYPE(0xA9,'l','y','r'); // lyrics +const AP4_Atom::Type AP4_ATOM_TYPE_TRKN = AP4_ATOM_TYPE('t','r','k','n'); // track# +const AP4_Atom::Type AP4_ATOM_TYPE_DISK = AP4_ATOM_TYPE('d','i','s','k'); // disk# +const AP4_Atom::Type AP4_ATOM_TYPE_COVR = AP4_ATOM_TYPE('c','o','v','r'); // cover art +const AP4_Atom::Type AP4_ATOM_TYPE_DESC = AP4_ATOM_TYPE('d','e','s','c'); // description +const AP4_Atom::Type AP4_ATOM_TYPE_CPIL = AP4_ATOM_TYPE('c','p','i','l'); // compilation? +const AP4_Atom::Type AP4_ATOM_TYPE_TMPO = AP4_ATOM_TYPE('t','m','p','o'); // tempo +const AP4_Atom::Type AP4_ATOM_TYPE_apID = AP4_ATOM_TYPE('a','p','I','D'); +const AP4_Atom::Type AP4_ATOM_TYPE_cnID = AP4_ATOM_TYPE('c','n','I','D'); +const AP4_Atom::Type AP4_ATOM_TYPE_cmID = AP4_ATOM_TYPE('c','m','I','D'); +const AP4_Atom::Type AP4_ATOM_TYPE_atID = AP4_ATOM_TYPE('a','t','I','D'); +const AP4_Atom::Type AP4_ATOM_TYPE_plID = AP4_ATOM_TYPE('p','l','I','D'); +const AP4_Atom::Type AP4_ATOM_TYPE_geID = AP4_ATOM_TYPE('g','e','I','D'); +const AP4_Atom::Type AP4_ATOM_TYPE_sfID = AP4_ATOM_TYPE('s','f','I','D'); +const AP4_Atom::Type AP4_ATOM_TYPE_akID = AP4_ATOM_TYPE('a','k','I','D'); +const AP4_Atom::Type AP4_ATOM_TYPE_aART = AP4_ATOM_TYPE('a','A','R','T'); +const AP4_Atom::Type AP4_ATOM_TYPE_TVNN = AP4_ATOM_TYPE('t','v','n','n'); // TV network +const AP4_Atom::Type AP4_ATOM_TYPE_TVSH = AP4_ATOM_TYPE('t','v','s','h'); // TV show +const AP4_Atom::Type AP4_ATOM_TYPE_TVEN = AP4_ATOM_TYPE('t','v','e','n'); // TV episode name +const AP4_Atom::Type AP4_ATOM_TYPE_TVSN = AP4_ATOM_TYPE('t','v','s','n'); // TV show season # +const AP4_Atom::Type AP4_ATOM_TYPE_TVES = AP4_ATOM_TYPE('t','v','e','s'); // TV show episode # +const AP4_Atom::Type AP4_ATOM_TYPE_STIK = AP4_ATOM_TYPE('s','t','i','k'); +const AP4_Atom::Type AP4_ATOM_TYPE_PCST = AP4_ATOM_TYPE('p','c','s','t'); // Podcast? +const AP4_Atom::Type AP4_ATOM_TYPE_PURD = AP4_ATOM_TYPE('p','u','r','d'); // +const AP4_Atom::Type AP4_ATOM_TYPE_PURL = AP4_ATOM_TYPE('p','u','r','l'); // Podcast URL (binary) +const AP4_Atom::Type AP4_ATOM_TYPE_EGID = AP4_ATOM_TYPE('e','g','i','d'); // +const AP4_Atom::Type AP4_ATOM_TYPE_PGAP = AP4_ATOM_TYPE('p','g','a','p'); // Gapless Playback +const AP4_Atom::Type AP4_ATOM_TYPE_CATG = AP4_ATOM_TYPE('c','a','t','g'); // Category +const AP4_Atom::Type AP4_ATOM_TYPE_KEYW = AP4_ATOM_TYPE('k','e','y','w'); // Keywords +const AP4_Atom::Type AP4_ATOM_TYPE_SONM = AP4_ATOM_TYPE('s','o','n','m'); // Sort-Order: Name +const AP4_Atom::Type AP4_ATOM_TYPE_SOAL = AP4_ATOM_TYPE('s','o','a','l'); // Sort-Order: Album +const AP4_Atom::Type AP4_ATOM_TYPE_SOAR = AP4_ATOM_TYPE('s','o','a','r'); // Sort-Order: Artist +const AP4_Atom::Type AP4_ATOM_TYPE_SOAA = AP4_ATOM_TYPE('s','o','a','a'); // Sort-Order: Album Artist +const AP4_Atom::Type AP4_ATOM_TYPE_SOCO = AP4_ATOM_TYPE('s','o','c','o'); // Sort-Order: Composer +const AP4_Atom::Type AP4_ATOM_TYPE_SOSN = AP4_ATOM_TYPE('s','o','s','n'); // Sort-Order: Show + +const AP4_Atom::Type AP4_ATOM_TYPE_TITL = AP4_ATOM_TYPE('t','i','t','l'); // 3GPP: title +const AP4_Atom::Type AP4_ATOM_TYPE_DSCP = AP4_ATOM_TYPE('d','s','c','p'); // 3GPP: description +const AP4_Atom::Type AP4_ATOM_TYPE_CPRT = AP4_ATOM_TYPE('c','p','r','t'); // 3GPP, ISO or ILST: copyright +const AP4_Atom::Type AP4_ATOM_TYPE_PERF = AP4_ATOM_TYPE('p','e','r','f'); // 3GPP: performer +const AP4_Atom::Type AP4_ATOM_TYPE_AUTH = AP4_ATOM_TYPE('a','u','t','h'); // 3GPP: author +const AP4_Atom::Type AP4_ATOM_TYPE_GNRE = AP4_ATOM_TYPE('g','n','r','e'); // 3GPP or ILST: genre (in 3GPP -> string, in ILST -> ID3v1 index + 1) +const AP4_Atom::Type AP4_ATOM_TYPE_RTNG = AP4_ATOM_TYPE('r','t','n','g'); // 3GPP or ILST: rating +const AP4_Atom::Type AP4_ATOM_TYPE_CLSF = AP4_ATOM_TYPE('c','l','s','f'); // 3GPP: classification +const AP4_Atom::Type AP4_ATOM_TYPE_KYWD = AP4_ATOM_TYPE('k','y','w','d'); // 3GPP: keywords +const AP4_Atom::Type AP4_ATOM_TYPE_LOCI = AP4_ATOM_TYPE('l','o','c','i'); // 3GPP: location information +const AP4_Atom::Type AP4_ATOM_TYPE_ALBM = AP4_ATOM_TYPE('a','l','b','m'); // 3GPP: album title and track number +const AP4_Atom::Type AP4_ATOM_TYPE_YRRC = AP4_ATOM_TYPE('y','r','r','c'); // 3GPP: recording year +const AP4_Atom::Type AP4_ATOM_TYPE_TSEL = AP4_ATOM_TYPE('t','s','e','l'); // 3GPP: track selection + +const AP4_Atom::Type AP4_ATOM_TYPE_ICNU = AP4_ATOM_TYPE('i','c','n','u'); // DCF: icon URI (OMA DCF 2.1) +const AP4_Atom::Type AP4_ATOM_TYPE_INFU = AP4_ATOM_TYPE('i','n','f','u'); // DCF: info URI (OMA DCF 2.1) +const AP4_Atom::Type AP4_ATOM_TYPE_CVRU = AP4_ATOM_TYPE('c','v','r','u'); // DCF: cover art URI (OMA DCF 2.1) +const AP4_Atom::Type AP4_ATOM_TYPE_LRCU = AP4_ATOM_TYPE('l','r','c','u'); // DCF: lyrics URI (OMA DCF 2.1) +const AP4_Atom::Type AP4_ATOM_TYPE_DCFD = AP4_ATOM_TYPE('d','c','f','D'); // DCF: duration (OMarlin) + +/*---------------------------------------------------------------------- +| AP4_MetaData ++---------------------------------------------------------------------*/ +class AP4_MetaData { +public: + class Key { + public: + // constructors + Key(const char* name, const char* ns) : + m_Name(name), m_Namespace(ns) {} + + // methods + const AP4_String& GetNamespace() const { return m_Namespace; } + const AP4_String& GetName() const { return m_Name; } + + private: + // members + const AP4_String m_Name; + const AP4_String m_Namespace; + }; + + class Value { + public: + // types + typedef enum { + TYPE_BINARY, + TYPE_STRING_UTF_8, + TYPE_STRING_UTF_16, + TYPE_STRING_PASCAL, + TYPE_GIF, + TYPE_JPEG, + TYPE_INT_08_BE, + TYPE_INT_16_BE, + TYPE_INT_32_BE, + TYPE_FLOAT_32_BE, + TYPE_FLOAT_64_BE + } Type; + + typedef enum { + TYPE_CATEGORY_STRING, + TYPE_CATEGORY_BINARY, + TYPE_CATEGORY_INTEGER, + TYPE_CATEGORY_FLOAT + } TypeCategory; + + typedef enum { + MEANING_UNKNOWN, + MEANING_ID3_GENRE, + MEANING_BOOLEAN, + MEANING_FILE_KIND, + MEANING_BINARY_ENCODED_CHARS + } Meaning; + + // destructor + virtual ~Value() {} + + // methods + Type GetType() const { return m_Type; } + TypeCategory GetTypeCategory() const; + Meaning GetMeaning() const { return m_Meaning; } + const AP4_String& GetLanguage() const { return m_Language; } + void SetLanguage(const char* language) { m_Language = language; } + virtual AP4_String ToString() const = 0; + virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const = 0; + virtual long ToInteger() const = 0; + + protected: + // class methods + static TypeCategory MapTypeToCategory(Type type); + + // constructor + Value(Type type, + Meaning meaning = MEANING_UNKNOWN, + const char* language = NULL) : + m_Type(type), m_Meaning(meaning), m_Language(language) {} + + // members + Type m_Type; + Meaning m_Meaning; + AP4_String m_Language; + }; + + class KeyInfo { + public: + // members + const char* name; + const char* description; + AP4_UI32 four_cc; + Value::Type value_type; + }; + + class Entry { + public: + // constructor + Entry(const char* name, const char* ns, Value* value) : + m_Key(name, ns), m_Value(value) {} + + // destructor + ~Entry() { delete m_Value; } + + // methods + AP4_Result AddToFile(AP4_File& file, AP4_Ordinal index = 0); + AP4_Result AddToFileIlst(AP4_File& file, AP4_Ordinal index = 0); + AP4_Result AddToFileDcf(AP4_File& file, AP4_Ordinal index = 0); + AP4_Result RemoveFromFile(AP4_File& file, AP4_Ordinal index); + AP4_Result RemoveFromFileIlst(AP4_File& file, AP4_Ordinal index); + AP4_Result RemoveFromFileDcf(AP4_File& file, AP4_Ordinal index); + AP4_ContainerAtom* FindInIlst(AP4_ContainerAtom* ilst) const; + AP4_Result ToAtom(AP4_Atom*& atom) const; + + // members + Key m_Key; + Value* m_Value; + }; + + // class members + static AP4_Array<KeyInfo> KeyInfos; + + // constructor + AP4_MetaData(AP4_File* file); + + // methods + AP4_Result ParseMoov(AP4_MoovAtom* moov); + AP4_Result ParseUdta(AP4_ContainerAtom* udta, const char* namespc); + + // destructor + ~AP4_MetaData(); + + // accessors + const AP4_List<Entry>& GetEntries() const { return m_Entries; } + + // methods + AP4_Result ResolveKeyName(AP4_Atom::Type atom_type, AP4_String& value); + AP4_Result AddIlstEntries(AP4_ContainerAtom* atom, const char* namespc); + AP4_Result Add3GppEntry(AP4_3GppLocalizedStringAtom* atom, const char* namespc); + AP4_Result AddDcfStringEntry(AP4_DcfStringAtom* atom, const char* namespc); + AP4_Result AddDcfdEntry(AP4_DcfdAtom* atom, const char* namespc); + +private: + // members + AP4_List<Entry> m_Entries; +}; + +/*---------------------------------------------------------------------- +| AP4_MetaDataAtomTypeHandler ++---------------------------------------------------------------------*/ +class AP4_MetaDataAtomTypeHandler : public AP4_AtomFactory::TypeHandler +{ +public: + // constructor + AP4_MetaDataAtomTypeHandler(AP4_AtomFactory* atom_factory) : + m_AtomFactory(atom_factory) {} + virtual AP4_Result CreateAtom(AP4_Atom::Type type, + AP4_UI32 size, + AP4_ByteStream& stream, + AP4_Atom::Type context, + AP4_Atom*& atom); + + // types + struct TypeList { + const AP4_Atom::Type* m_Types; + AP4_Size m_Size; + }; + + // class constants + static const AP4_Atom::Type IlstTypes[]; + static const TypeList IlstTypeList; + static const AP4_Atom::Type _3gppLocalizedStringTypes[]; + static const TypeList _3gppLocalizedStringTypeList; + static const AP4_Atom::Type _3gppOtherTypes[]; + static const TypeList _3gppOtherTypeList; + static const AP4_Atom::Type DcfStringTypes[]; + static const TypeList DcfStringTypeList; + + // class methods + static bool IsTypeInList(AP4_Atom::Type type, const TypeList& list); + +private: + // members + AP4_AtomFactory* m_AtomFactory; +}; + +/*---------------------------------------------------------------------- +| AP4_MetaDataTag ++---------------------------------------------------------------------*/ +class AP4_MetaDataTag +{ +public: + + // destructor + virtual ~AP4_MetaDataTag() {} + + // methods + virtual AP4_Result Write(AP4_ByteStream& stream); + virtual AP4_Result Inspect(AP4_AtomInspector& inspector); + +protected: + // constructor + AP4_MetaDataTag(AP4_UI32 data_type, + AP4_UI32 data_lang, + AP4_Size size, + AP4_ByteStream& stream); + +}; + +/*---------------------------------------------------------------------- +| AP4_3GppLocalizedStringAtom ++---------------------------------------------------------------------*/ +class AP4_3GppLocalizedStringAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_3GppLocalizedStringAtom, AP4_Atom) + + // factory method + static AP4_3GppLocalizedStringAtom* Create(Type type, AP4_UI32 size, AP4_ByteStream& stream); + + // constructor + AP4_3GppLocalizedStringAtom(Type type, const char* language, const char* value); + AP4_3GppLocalizedStringAtom(Type type, + AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // AP4_Atom methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // methods + const char* GetLanguage() const { return m_Language; } + const AP4_String& GetValue() const { return m_Value; } + +private: + // members + char m_Language[4]; + AP4_String m_Value; +}; + +/*---------------------------------------------------------------------- +| AP4_DcfStringAtom ++---------------------------------------------------------------------*/ +class AP4_DcfStringAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_DcfStringAtom, AP4_Atom) + + // factory method + static AP4_DcfStringAtom* Create(Type type, AP4_UI32 size, AP4_ByteStream& stream); + + // constructor + AP4_DcfStringAtom(Type type, const char* value); + AP4_DcfStringAtom(Type type, + AP4_UI32 size, + AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + + // AP4_Atom methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // methods + const AP4_String& GetValue() const { return m_Value; } + +private: + // members + AP4_String m_Value; +}; + +/*---------------------------------------------------------------------- +| AP4_DcfdAtom ++---------------------------------------------------------------------*/ +class AP4_DcfdAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_DcfdAtom, AP4_Atom) + + // factory method + static AP4_DcfdAtom* Create(AP4_UI32 size, AP4_ByteStream& stream); + + // constructors + AP4_DcfdAtom(AP4_UI32 version, + AP4_UI32 flags, + AP4_ByteStream& stream); + AP4_DcfdAtom(AP4_UI32 duration); + + // AP4_Atom methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // methods + AP4_UI32 GetDuration() const { return m_Duration; } + +private: + // members + AP4_UI32 m_Duration; +}; + +/*---------------------------------------------------------------------- +| AP4_MetaDataStringAtom ++---------------------------------------------------------------------*/ +class AP4_MetaDataStringAtom : public AP4_Atom +{ +public: + // constructors + AP4_MetaDataStringAtom(Type type, const char* value); + AP4_MetaDataStringAtom(Type type, AP4_UI32 size, AP4_ByteStream& stream); + + // AP4_Atom methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // methods + const AP4_String& GetValue() { return m_Value; } + +private: + // members + AP4_UI32 m_Reserved; + AP4_String m_Value; +}; + +/*---------------------------------------------------------------------- +| AP4_DataAtom ++---------------------------------------------------------------------*/ +class AP4_DataAtom : public AP4_Atom +{ +public: + AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_DataAtom, AP4_Atom) + + typedef enum { + DATA_TYPE_BINARY = 0, + DATA_TYPE_STRING_UTF_8 = 1, + DATA_TYPE_STRING_UTF_16 = 2, + DATA_TYPE_STRING_PASCAL = 3, + DATA_TYPE_GIF = 13, + DATA_TYPE_JPEG = 14, + DATA_TYPE_SIGNED_INT_BE = 21, /* the size of the integer is derived from the container size */ + DATA_TYPE_FLOAT_32_BE = 22, + DATA_TYPE_FLOAT_64_BE = 23 + } DataType; + + typedef enum { + LANGUAGE_ENGLISH = 0 + } DataLang; + + // constructors + AP4_DataAtom(const AP4_MetaData::Value& value); + AP4_DataAtom(AP4_UI32 size, AP4_ByteStream& stream); + + // destructor + ~AP4_DataAtom(); + + // AP4_Atom methods + virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); + virtual AP4_Result WriteFields(AP4_ByteStream& stream); + + // accessors + DataType GetDataType() { return m_DataType; } + DataLang GetDataLang() { return m_DataLang; } + AP4_MetaData::Value::Type GetValueType(); + + // methods + AP4_Result LoadString(AP4_String*& string); + AP4_Result LoadBytes(AP4_DataBuffer& bytes); + AP4_Result LoadInteger(long& value); + +private: + // members + DataType m_DataType; + DataLang m_DataLang; + AP4_ByteStream* m_Source; +}; + +/*---------------------------------------------------------------------- +| AP4_StringMetaDataValue ++---------------------------------------------------------------------*/ +class AP4_StringMetaDataValue : public AP4_MetaData::Value { +public: + // constructor + AP4_StringMetaDataValue(const char* value, const char* language=NULL) : + Value(TYPE_STRING_UTF_8, MEANING_UNKNOWN, language), + m_Value(value) {} + + // AP4_MetaData::Value methods + virtual AP4_String ToString() const; + virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const; + virtual long ToInteger() const; + +private: + // members + AP4_String m_Value; +}; + +/*---------------------------------------------------------------------- +| AP4_IntegerMetaDataValue ++---------------------------------------------------------------------*/ +class AP4_IntegerMetaDataValue : public AP4_MetaData::Value { +public: + // constructor + AP4_IntegerMetaDataValue(Type type, long value) : + Value(type), m_Value(value) {} + + // AP4_MetaData::Value methods + virtual AP4_String ToString() const; + virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const; + virtual long ToInteger() const; + +private: + // members + long m_Value; +}; + +/*---------------------------------------------------------------------- +| AP4_BinaryMetaDataValue ++---------------------------------------------------------------------*/ +class AP4_BinaryMetaDataValue : public AP4_MetaData::Value { +public: + // constructor + AP4_BinaryMetaDataValue(Type type, const AP4_UI08* data, AP4_Size size) : + Value(type), m_Value(data, size) {} + + // AP4_MetaData::Value methods + virtual AP4_String ToString() const; + virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const; + virtual long ToInteger() const; + +private: + // members + AP4_DataBuffer m_Value; +}; + +/*---------------------------------------------------------------------- +| AP4_AtomMetaDataValue ++---------------------------------------------------------------------*/ +class AP4_AtomMetaDataValue : public AP4_MetaData::Value +{ +public: + // constructor + AP4_AtomMetaDataValue(AP4_DataAtom* data_atom, AP4_UI32 parent_type); + + // AP4_MetaData::Value methods + virtual AP4_String ToString() const; + virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const; + virtual long ToInteger() const; + +private: + // members + AP4_DataAtom* m_DataAtom; +}; + +#endif // _AP4_META_DATA_H_ diff --git a/src/filters/parser/mp4splitter/Ap4AsyncReaderStream.cpp b/src/filters/parser/mp4splitter/Ap4AsyncReaderStream.cpp index 4fce5813c..d298660f9 100644 --- a/src/filters/parser/mp4splitter/Ap4AsyncReaderStream.cpp +++ b/src/filters/parser/mp4splitter/Ap4AsyncReaderStream.cpp @@ -25,13 +25,13 @@ void AP4_AsyncReaderStream::Release() if(--m_refs == 0) delete this;
}
-AP4_Result AP4_AsyncReaderStream::Read(void* buffer, AP4_Size bytesToRead, AP4_Size* bytesRead)
+AP4_Result AP4_AsyncReaderStream::ReadPartial(void* buffer, AP4_Size bytesToRead, AP4_Size& bytesRead)
{
AP4_Size bytesAvail = (AP4_Size)m_pFile->GetRemaining();
if(bytesAvail < bytesToRead)
{
- if(bytesRead) *bytesRead = bytesAvail;
+ bytesRead = bytesAvail;
bytesToRead = bytesAvail;
}
@@ -42,34 +42,34 @@ AP4_Result AP4_AsyncReaderStream::Read(void* buffer, AP4_Size bytesToRead, AP4_S if(FAILED(m_pFile->ByteRead((BYTE*)buffer, bytesToRead)))
{
- if(bytesRead) *bytesRead = 0;
+ bytesRead = 0;
return AP4_ERROR_READ_FAILED;
}
- if(bytesRead) *bytesRead = bytesToRead;
+ bytesRead = bytesToRead;
return AP4_SUCCESS;
}
-AP4_Result AP4_AsyncReaderStream::Write(const void* buffer, AP4_Size bytesToWrite, AP4_Size* bytesWritten)
+AP4_Result AP4_AsyncReaderStream::WritePartial(const void* buffer, AP4_Size bytesToWrite, AP4_Size& bytesWritten)
{
return AP4_ERROR_WRITE_FAILED;
}
-AP4_Result AP4_AsyncReaderStream::Seek(AP4_Offset offset)
+AP4_Result AP4_AsyncReaderStream::Seek(AP4_Position offset)
{
m_pFile->Seek(offset);
return m_pFile->GetPos() == offset ? AP4_SUCCESS : AP4_FAILURE;
}
-AP4_Result AP4_AsyncReaderStream::Tell(AP4_Offset& offset)
+AP4_Result AP4_AsyncReaderStream::Tell(AP4_Position& offset)
{
offset = (AP4_Offset)m_pFile->GetPos();
return AP4_SUCCESS;
}
-AP4_Result AP4_AsyncReaderStream::GetSize(AP4_Size& size)
+AP4_Result AP4_AsyncReaderStream::GetSize(AP4_LargeSize& size)
{
- size = (AP4_Size)m_pFile->GetLength();
+ size = m_pFile->GetLength();
return AP4_SUCCESS;
}
\ No newline at end of file diff --git a/src/filters/parser/mp4splitter/Ap4AsyncReaderStream.h b/src/filters/parser/mp4splitter/Ap4AsyncReaderStream.h index 3ac34e4ad..9e5ba4b28 100644 --- a/src/filters/parser/mp4splitter/Ap4AsyncReaderStream.h +++ b/src/filters/parser/mp4splitter/Ap4AsyncReaderStream.h @@ -26,9 +26,9 @@ public: void AddReference();
void Release();
- AP4_Result Read(void* buffer, AP4_Size bytesToRead, AP4_Size* bytesRead);
- AP4_Result Write(const void* buffer, AP4_Size bytesToWrite, AP4_Size* bytesWritten);
- AP4_Result Seek(AP4_Offset offset);
- AP4_Result Tell(AP4_Offset& offset);
- AP4_Result GetSize(AP4_Size& size);
+ virtual AP4_Result ReadPartial(void* buffer, AP4_Size bytesToRead, AP4_Size& bytesRead);
+ virtual AP4_Result WritePartial(const void* buffer, AP4_Size bytesToWrite, AP4_Size& bytesWritten);
+ virtual AP4_Result Seek(AP4_Position offset);
+ virtual AP4_Result Tell(AP4_Position& offset);
+ virtual AP4_Result GetSize(AP4_LargeSize& size);
};
\ No newline at end of file diff --git a/src/filters/parser/mp4splitter/MP4Splitter.cpp b/src/filters/parser/mp4splitter/MP4Splitter.cpp index e6d4d29dd..81e3d993f 100644 --- a/src/filters/parser/mp4splitter/MP4Splitter.cpp +++ b/src/filters/parser/mp4splitter/MP4Splitter.cpp @@ -35,7 +35,7 @@ #include "Ap4AvcCAtom.h"
#include "Ap4ChplAtom.h"
#include "Ap4FtabAtom.h"
-#include "Ap4DataAtom.h"
+#include "Ap4MetaData.h"
#ifdef REGISTER_FILTER
@@ -154,8 +154,8 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) if(!AP4_SUCCEEDED(track->GetSample(0, sample)) || sample.GetDescriptionIndex() == 0xFFFFFFFF)
continue;
- CStringW TrackName = UTF8To16(track->GetTrackName().c_str());
- CStringA TrackLanguage = track->GetTrackLanguage().c_str();
+ CStringW TrackName = UTF8To16(track->GetTrackName().GetChars());
+ CStringA TrackLanguage = track->GetTrackLanguage().GetChars();
CAtlArray<CMediaType> mts;
@@ -175,35 +175,35 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) {
mpeg_desc = dynamic_cast<AP4_MpegSampleDescription*>(desc);
}
- else if(desc->GetType() == AP4_SampleDescription::TYPE_ISMACRYP)
+ else if(desc->GetType() == AP4_SampleDescription::TYPE_PROTECTED)
{
- AP4_IsmaCrypSampleDescription* isma_desc = dynamic_cast<AP4_IsmaCrypSampleDescription*>(desc);
- mpeg_desc = isma_desc->GetOriginalSampleDescription();
+ AP4_ProtectedSampleDescription* isma_desc = dynamic_cast<AP4_ProtectedSampleDescription*>(desc);
+ mpeg_desc = dynamic_cast<AP4_MpegSampleDescription*>(isma_desc->GetOriginalSampleDescription());
}
if(AP4_MpegVideoSampleDescription* video_desc =
dynamic_cast<AP4_MpegVideoSampleDescription*>(mpeg_desc))
{
- const AP4_DataBuffer* di = video_desc->GetDecoderInfo();
- if(!di) di = ∅
+ const AP4_DataBuffer& di = video_desc->GetDecoderInfo();
+ //if(!di) di = ∅
mt.majortype = MEDIATYPE_Video;
mt.formattype = FORMAT_VideoInfo;
- vih = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER) + di->GetDataSize());
+ vih = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER) + di.GetDataSize());
memset(vih, 0, mt.FormatLength());
vih->dwBitRate = video_desc->GetAvgBitrate()/8;
vih->bmiHeader.biSize = sizeof(vih->bmiHeader);
vih->bmiHeader.biWidth = (LONG)video_desc->GetWidth();
vih->bmiHeader.biHeight = (LONG)video_desc->GetHeight();
- memcpy(vih + 1, di->GetData(), di->GetDataSize());
+ memcpy(vih + 1, di.GetData(), di.GetDataSize());
switch(video_desc->GetObjectTypeId())
{
- case AP4_MPEG4_VISUAL_OTI:
+ case AP4_OTI_MPEG4_VISUAL:
mt.subtype = FOURCCMap('v4pm');
mt.formattype = FORMAT_MPEG2Video;
{
- MPEG2VIDEOINFO* vih = (MPEG2VIDEOINFO*)mt.AllocFormatBuffer(FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + di->GetDataSize());
+ MPEG2VIDEOINFO* vih = (MPEG2VIDEOINFO*)mt.AllocFormatBuffer(FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + di.GetDataSize());
memset(vih, 0, mt.FormatLength());
vih->hdr.bmiHeader.biSize = sizeof(vih->hdr.bmiHeader);
vih->hdr.bmiHeader.biWidth = (LONG)video_desc->GetWidth();
@@ -213,19 +213,19 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) vih->hdr.bmiHeader.biBitCount = 24;
vih->hdr.dwPictAspectRatioX = vih->hdr.bmiHeader.biWidth;
vih->hdr.dwPictAspectRatioY = vih->hdr.bmiHeader.biHeight;
- vih->cbSequenceHeader = di->GetDataSize();
- memcpy(vih->dwSequenceHeader, di->GetData(), di->GetDataSize());
+ vih->cbSequenceHeader = di.GetDataSize();
+ memcpy(vih->dwSequenceHeader, di.GetData(), di.GetDataSize());
mts.Add(mt);
mt.subtype = FOURCCMap(vih->hdr.bmiHeader.biCompression = 'V4PM');
mts.Add(mt);
}
break;
- case AP4_MPEG2_VISUAL_SIMPLE_OTI:
- case AP4_MPEG2_VISUAL_MAIN_OTI:
- case AP4_MPEG2_VISUAL_SNR_OTI:
- case AP4_MPEG2_VISUAL_SPATIAL_OTI:
- case AP4_MPEG2_VISUAL_HIGH_OTI:
- case AP4_MPEG2_VISUAL_422_OTI:
+ case AP4_OTI_MPEG2_VISUAL_SIMPLE:
+ case AP4_OTI_MPEG2_VISUAL_MAIN:
+ case AP4_OTI_MPEG2_VISUAL_SNR:
+ case AP4_OTI_MPEG2_VISUAL_SPATIAL:
+ case AP4_OTI_MPEG2_VISUAL_HIGH:
+ case AP4_OTI_MPEG2_VISUAL_422:
mt.subtype = MEDIASUBTYPE_MPEG2_VIDEO;
{
m_pFile->Seek(sample.GetOffset());
@@ -236,7 +236,7 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) }
mts.Add(mt);
break;
- case AP4_MPEG1_VISUAL_OTI: // ???
+ case AP4_OTI_MPEG1_VISUAL: // ???
mt.subtype = MEDIASUBTYPE_MPEG1Payload;
{
m_pFile->Seek(sample.GetOffset());
@@ -257,33 +257,33 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) else if(AP4_MpegAudioSampleDescription* audio_desc =
dynamic_cast<AP4_MpegAudioSampleDescription*>(mpeg_desc))
{
- const AP4_DataBuffer* di = audio_desc->GetDecoderInfo();
- if(!di) di = ∅
+ const AP4_DataBuffer& di = audio_desc->GetDecoderInfo();
+ //if(!di) di = ∅
mt.majortype = MEDIATYPE_Audio;
mt.formattype = FORMAT_WaveFormatEx;
- wfe = (WAVEFORMATEX*)mt.AllocFormatBuffer(sizeof(WAVEFORMATEX) + di->GetDataSize());
+ wfe = (WAVEFORMATEX*)mt.AllocFormatBuffer(sizeof(WAVEFORMATEX) + di.GetDataSize());
memset(wfe, 0, mt.FormatLength());
wfe->nSamplesPerSec = audio_desc->GetSampleRate();
wfe->nAvgBytesPerSec = audio_desc->GetAvgBitrate()/8;
wfe->nChannels = audio_desc->GetChannelCount();
wfe->wBitsPerSample = audio_desc->GetSampleSize();
- wfe->cbSize = (WORD)di->GetDataSize();
- memcpy(wfe + 1, di->GetData(), di->GetDataSize());
+ wfe->cbSize = (WORD)di.GetDataSize();
+ memcpy(wfe + 1, di.GetData(), di.GetDataSize());
switch(audio_desc->GetObjectTypeId())
{
- case AP4_MPEG4_AUDIO_OTI:
- case AP4_MPEG2_AAC_AUDIO_MAIN_OTI: // ???
- case AP4_MPEG2_AAC_AUDIO_LC_OTI: // ???
- case AP4_MPEG2_AAC_AUDIO_SSRP_OTI: // ???
+ case AP4_OTI_MPEG4_AUDIO:
+ case AP4_OTI_MPEG2_AAC_AUDIO_MAIN: // ???
+ case AP4_OTI_MPEG2_AAC_AUDIO_LC: // ???
+ case AP4_OTI_MPEG2_AAC_AUDIO_SSRP: // ???
mt.subtype = FOURCCMap(wfe->wFormatTag = WAVE_FORMAT_AAC);
if(wfe->cbSize >= 2) wfe->nChannels = (((BYTE*)(wfe+1))[1]>>3) & 0xf;
mts.Add(mt);
break;
- case AP4_MPEG2_PART3_AUDIO_OTI: // ???
- case AP4_MPEG1_AUDIO_OTI:
+ case AP4_OTI_MPEG2_PART3_AUDIO: // ???
+ case AP4_OTI_MPEG1_AUDIO:
mt.subtype = FOURCCMap(wfe->wFormatTag = WAVE_FORMAT_MP3);
{
m_pFile->Seek(sample.GetOffset());
@@ -304,13 +304,13 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) else if(AP4_MpegSystemSampleDescription* system_desc =
dynamic_cast<AP4_MpegSystemSampleDescription*>(desc))
{
- const AP4_DataBuffer* di = system_desc->GetDecoderInfo();
- if(!di) di = ∅
+ const AP4_DataBuffer& di = system_desc->GetDecoderInfo();
+ //if(!di) di = ∅
switch(system_desc->GetObjectTypeId())
{
case AP4_NERO_VOBSUB:
- if(di->GetDataSize() >= 16*4)
+ if(di.GetDataSize() >= 16*4)
{
CSize size(720, 576);
if(AP4_TkhdAtom* tkhd = dynamic_cast<AP4_TkhdAtom*>(track->GetTrakAtom()->GetChild(AP4_ATOM_TYPE_TKHD)))
@@ -319,7 +319,7 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) size.cy = tkhd->GetHeight()>>16;
}
- const AP4_Byte* pal = di->GetData();
+ const AP4_Byte* pal = di.GetData();
CAtlList<CStringA> sl;
for(int i = 0; i < 16*4; i += 4)
{
@@ -361,49 +361,14 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) TRACE(_T("Unknown audio OBI: %02x\n"), system_desc->GetObjectTypeId());
}
}
- else if(AP4_UnknownSampleDescription* unknown_desc =
- dynamic_cast<AP4_UnknownSampleDescription*>(desc)) // TEMP
+ else if(desc->GetType() == AP4_SampleDescription::TYPE_AVC)
{
- AP4_SampleEntry* sample_entry = unknown_desc->GetSampleEntry();
+ AP4_AvcSampleDescription* avc1 = dynamic_cast<AP4_AvcSampleDescription*>(desc);
+
+ const AP4_DataBuffer& di = avc1->GetRawBytes();
- if(dynamic_cast<AP4_TextSampleEntry*>(sample_entry)
- || dynamic_cast<AP4_Tx3gSampleEntry*>(sample_entry))
- {
- mt.majortype = MEDIATYPE_Subtitle;
- mt.subtype = MEDIASUBTYPE_ASS2;
- mt.formattype = FORMAT_SubtitleInfo;
- CStringA hdr;
- hdr.Format(
- "[Script Info]\n"
- "ScriptType: v4.00++\n"
- "ScaledBorderAndShadow: yes\n"
- "PlayResX: %d\n"
- "PlayResY: %d\n"
- "[V4++ Styles]\n"
- "Style: Text,Arial,12,&H00ffffff,&H0000ffff,&H00000000,&H80000000,0,0,0,0,100,100,0,0.00,3,0,0,2,0,0,0,0,1,1\n",
- // "Style: Text,Arial,12,&H00ffffff,&H0000ffff,&H00000000,&H80000000,0,0,0,0,100,100,0,0.00,1,0,0,2,0,0,0,0,1,1\n",
- m_framesize.cx,
- m_framesize.cy);
- SUBTITLEINFO* si = (SUBTITLEINFO*)mt.AllocFormatBuffer(sizeof(SUBTITLEINFO) + hdr.GetLength());
- memset(si, 0, mt.FormatLength());
- si->dwOffset = sizeof(SUBTITLEINFO);
- strcpy_s(si->IsoLang, countof(si->IsoLang), CStringA(TrackLanguage));
- wcscpy_s(si->TrackName, countof(si->TrackName), TrackName);
- memcpy(si + 1, (LPCSTR)hdr, hdr.GetLength());
- mts.Add(mt);
- }
- }
- }
- else if(AP4_Avc1SampleEntry* avc1 = dynamic_cast<AP4_Avc1SampleEntry*>(
- track->GetTrakAtom()->FindChild("mdia/minf/stbl/stsd/avc1")))
- {
- if(AP4_AvcCAtom* avcC = dynamic_cast<AP4_AvcCAtom*>(avc1->GetChild(AP4_ATOM_TYPE_AVCC)))
- {
- const AP4_DataBuffer* di = avcC->GetDecoderInfo();
- if(!di) di = ∅
-
- const AP4_Byte* data = di->GetData();
- AP4_Size size = di->GetDataSize();
+ const AP4_Byte* data = di.GetData();
+ AP4_Size size = di.GetDataSize();
mt.majortype = MEDIATYPE_Video;
mt.subtype = FOURCCMap('1cva');
@@ -452,10 +417,10 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) mts.Add(mt);
}
}
- else if(AP4_StsdAtom* stsd = dynamic_cast<AP4_StsdAtom*>(
+ if(AP4_StsdAtom* stsd = dynamic_cast<AP4_StsdAtom*>(
track->GetTrakAtom()->FindChild("mdia/minf/stbl/stsd")))
{
- const AP4_DataBuffer& db = stsd->GetDataBuffer();
+ const AP4_DataBuffer& db = AP4_DataBuffer();//stsd->GetDataBuffer();
for(AP4_List<AP4_Atom>::Item* item = stsd->GetChildren().FirstItem();
item;
@@ -541,6 +506,34 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) mts.Add(mt);
break;
}
+
+ else if(dynamic_cast<AP4_TextSampleEntry*>(atom)
+ || dynamic_cast<AP4_Tx3gSampleEntry*>(atom))
+ {
+ mt.majortype = MEDIATYPE_Subtitle;
+ mt.subtype = MEDIASUBTYPE_ASS2;
+ mt.formattype = FORMAT_SubtitleInfo;
+ CStringA hdr;
+ hdr.Format(
+ "[Script Info]\n"
+ "ScriptType: v4.00++\n"
+ "ScaledBorderAndShadow: yes\n"
+ "PlayResX: %d\n"
+ "PlayResY: %d\n"
+ "[V4++ Styles]\n"
+ "Style: Text,Arial,12,&H00ffffff,&H0000ffff,&H00000000,&H80000000,0,0,0,0,100,100,0,0.00,3,0,0,2,0,0,0,0,1,1\n",
+ // "Style: Text,Arial,12,&H00ffffff,&H0000ffff,&H00000000,&H80000000,0,0,0,0,100,100,0,0.00,1,0,0,2,0,0,0,0,1,1\n",
+ m_framesize.cx,
+ m_framesize.cy);
+ SUBTITLEINFO* si = (SUBTITLEINFO*)mt.AllocFormatBuffer(sizeof(SUBTITLEINFO) + hdr.GetLength());
+ memset(si, 0, mt.FormatLength());
+ si->dwOffset = sizeof(SUBTITLEINFO);
+ strcpy_s(si->IsoLang, countof(si->IsoLang), CStringA(TrackLanguage));
+ wcscpy_s(si->TrackName, countof(si->TrackName), TrackName);
+ memcpy(si + 1, (LPCSTR)hdr, hdr.GetLength());
+ mts.Add(mt);
+ }
+
}
}
@@ -610,7 +603,7 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) for(AP4_Cardinal i = 0; i < chapters.ItemCount(); i++)
{
AP4_ChplAtom::AP4_Chapter& chapter = chapters[i];
- ChapAppend(chapter.Time, UTF8To16(ConvertMBCS(chapter.Name.c_str(), ANSI_CHARSET, CP_UTF8))); // this is b0rked, thx to nero :P
+ ChapAppend(chapter.Time, UTF8To16(ConvertMBCS(chapter.Name.GetChars(), ANSI_CHARSET, CP_UTF8))); // this is b0rked, thx to nero :P
}
ChapSort();
@@ -628,33 +621,34 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) {
if(AP4_DataAtom* data = dynamic_cast<AP4_DataAtom*>(atom->GetChild(AP4_ATOM_TYPE_DATA)))
{
- const AP4_DataBuffer* db = data->GetData();
-
- if(atom->GetType() == AP4_ATOM_TYPE_TRKN)
- {
- if(db->GetDataSize() >= 4)
- {
- unsigned short n = (db->GetData()[2] << 8) | db->GetData()[3];
- if(n > 0 && n < 100) track.Format(L"%02d", n);
- else if(n >= 100) track.Format(L"%d", n);
- }
- }
- else
- {
- CStringW str = UTF8To16(CStringA((LPCSTR)db->GetData(), db->GetDataSize()));
-
- switch(atom->GetType())
- {
- case AP4_ATOM_TYPE_NAM: title = str; break;
- case AP4_ATOM_TYPE_ART: artist = str; break;
- case AP4_ATOM_TYPE_WRT: writer = str; break;
- case AP4_ATOM_TYPE_ALB: album = str; break;
- case AP4_ATOM_TYPE_DAY: year = str; break;
- case AP4_ATOM_TYPE_TOO: appl = str; break;
- case AP4_ATOM_TYPE_CMT: desc = str; break;
- case AP4_ATOM_TYPE_GEN: gen = str; break;
- }
- }
+ // TODO : BENTOMIGRATION
+ //const AP4_DataBuffer* db = data->GetData();
+
+ //if(atom->GetType() == AP4_ATOM_TYPE_TRKN)
+ //{
+ // if(db->GetDataSize() >= 4)
+ // {
+ // unsigned short n = (db->GetData()[2] << 8) | db->GetData()[3];
+ // if(n > 0 && n < 100) track.Format(L"%02d", n);
+ // else if(n >= 100) track.Format(L"%d", n);
+ // }
+ //}
+ //else
+ //{
+ // CStringW str = UTF8To16(CStringA((LPCSTR)db->GetData(), db->GetDataSize()));
+
+ // switch(atom->GetType())
+ // {
+ // case AP4_ATOM_TYPE_NAM: title = str; break;
+ // case AP4_ATOM_TYPE_ART: artist = str; break;
+ // case AP4_ATOM_TYPE_WRT: writer = str; break;
+ // case AP4_ATOM_TYPE_ALB: album = str; break;
+ // case AP4_ATOM_TYPE_DAY: year = str; break;
+ // case AP4_ATOM_TYPE_TOO: appl = str; break;
+ // case AP4_ATOM_TYPE_CMT: desc = str; break;
+ // case AP4_ATOM_TYPE_GEN: gen = str; break;
+ // }
+ //}
}
}
}
@@ -689,7 +683,7 @@ bool CMP4SplitterFilter::DemuxInit() POSITION pos = m_trackpos.GetStartPosition();
while(pos)
{
- CAtlMap<DWORD, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
+ CAtlMap<AP4_Ordinal, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
pPair->m_value.index = 0;
pPair->m_value.ts = 0;
@@ -706,14 +700,14 @@ bool CMP4SplitterFilter::DemuxInit() void CMP4SplitterFilter::DemuxSeek(REFERENCE_TIME rt)
{
- AP4_TimeStamp ts = (AP4_TimeStamp)(rt / 10000);
+ REFERENCE_TIME ts = (rt / 10000);
AP4_Movie* movie = (AP4_Movie*)m_pFile->GetMovie();
POSITION pos = m_trackpos.GetStartPosition();
while(pos)
{
- CAtlMap<DWORD, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
+ CAtlMap<AP4_Ordinal, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
AP4_Track* track = movie->GetTrack(pPair->m_key);
@@ -728,12 +722,13 @@ void CMP4SplitterFilter::DemuxSeek(REFERENCE_TIME rt) if(AP4_StssAtom* stss = dynamic_cast<AP4_StssAtom*>(track->GetTrakAtom()->FindChild("mdia/minf/stbl/stss")))
{
- if(stss->m_Entries.ItemCount() > 0)
+ const AP4_Array<AP4_UI32>& Entries = stss->GetEntries();
+ if(Entries.ItemCount() > 0)
{
AP4_Cardinal i = -1;
- while(++i < stss->m_Entries.ItemCount() && stss->m_Entries[i]-1 <= pPair->m_value.index);
+ while(++i < Entries.ItemCount() && Entries[i]-1 <= pPair->m_value.index);
if(i > 0) i--;
- pPair->m_value.index = stss->m_Entries[i]-1;
+ pPair->m_value.index = Entries[i]-1;
}
}
}
@@ -1005,13 +1000,13 @@ bool CMP4SplitterFilter::DemuxLoop() while(SUCCEEDED(hr) && !CheckRequest(NULL))
{
- CAtlMap<DWORD, trackpos>::CPair* pPairNext = NULL;
+ CAtlMap<AP4_Ordinal, trackpos>::CPair* pPairNext = NULL;
REFERENCE_TIME rtNext = 0;
POSITION pos = m_trackpos.GetStartPosition();
while(pos)
{
- CAtlMap<DWORD, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
+ CAtlMap<AP4_Ordinal, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
AP4_Track* track = movie->GetTrack(pPair->m_key);
@@ -1050,13 +1045,13 @@ bool CMP4SplitterFilter::DemuxLoop() if(AP4_StssAtom* stss = dynamic_cast<AP4_StssAtom*>(track->GetTrakAtom()->FindChild("mdia/minf/stbl/stss")))
{
- if(stss->m_Entries.ItemCount() > 0)
+ if(stss->GetEntries().ItemCount() > 0)
{
p->bSyncPoint = FALSE;
AP4_Cardinal i = -1;
- while(++i < stss->m_Entries.ItemCount())
- if(stss->m_Entries[i]-1 == pPairNext->m_value.index)
+ while(++i < stss->GetEntries().ItemCount())
+ if(stss->GetEntries()[i]-1 == pPairNext->m_value.index)
p->bSyncPoint = TRUE;
}
}
@@ -1132,62 +1127,10 @@ bool CMP4SplitterFilter::DemuxLoop() CPoint translation(0, 0);
if(AP4_TkhdAtom* tkhd = dynamic_cast<AP4_TkhdAtom*>(track->GetTrakAtom()->GetChild(AP4_ATOM_TYPE_TKHD)))
{
- AP4_Float x, y;
+ float x, y;
tkhd->GetTranslation(x, y);
translation.SetPoint((int)x, (int)y);
}
-
- if(AP4_UnknownSampleDescription* unknown_desc = dynamic_cast<AP4_UnknownSampleDescription*>(desc)) // TEMP
- {
- AP4_SampleEntry* sample_entry = unknown_desc->GetSampleEntry();
-
- if(AP4_TextSampleEntry* text = dynamic_cast<AP4_TextSampleEntry*>(sample_entry))
- {
- const AP4_TextSampleEntry::AP4_TextDescription& d = text->GetDescription();
-
- // TODO
- }
- else if(AP4_Tx3gSampleEntry* tx3g = dynamic_cast<AP4_Tx3gSampleEntry*>(sample_entry))
- {
- const AP4_Tx3gSampleEntry::AP4_Tx3gDescription& desc = tx3g->GetDescription();
-
- CStringW font = L"Arial";
-
- if(AP4_FtabAtom* ftab = dynamic_cast<AP4_FtabAtom*>(tx3g->GetChild(AP4_ATOM_TYPE_FTAB)))
- {
- AP4_String Name;
- if(AP4_SUCCEEDED(ftab->LookupFont(desc.Style.Font.Id, Name)))
- font = Name.c_str();
- }
-
- CRect rbox;
- CStringW ssa = ConvertTX3GToSSA(
- UTF8To16(str), desc, font,
- ptr + (2 + size), avail - (2 + size),
- m_framesize, translation,
- (p->rtStop - p->rtStart)/10000,
- rbox);
- dlgln = UTF16To8(ssa);
-
- const AP4_Byte* bclr = (const AP4_Byte*)&desc.BackgroundColor;
-
- if(bclr[3])
- {
- CPoint tl = rbox.TopLeft();
- rbox.OffsetRect(-tl.x, -tl.y);
-
- dlgln_bkg.Format(
- "0,-1,Text,,0,0,0,0,,{\\an7\\pos(%d,%d)\\1c%02x%02x%02x\\1a%02x\\bord0\\shad0}{\\p1}m %d %d l %d %d l %d %d l %d %d {\\p0}",
- tl.x, tl.y,
- bclr[2], bclr[1], bclr[0],
- 255 - bclr[3],
- rbox.left, rbox.top,
- rbox.right, rbox.top,
- rbox.right, rbox.bottom,
- rbox.left, rbox.bottom);
- }
- }
- }
}
dlgln.Replace("\r", "");
@@ -1251,7 +1194,7 @@ STDMETHODIMP CMP4SplitterFilter::GetKeyFrameCount(UINT& nKFs) POSITION pos = m_trackpos.GetStartPosition();
while(pos)
{
- CAtlMap<DWORD, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
+ CAtlMap<AP4_Ordinal, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
AP4_Track* track = movie->GetTrack(pPair->m_key);
@@ -1260,7 +1203,7 @@ STDMETHODIMP CMP4SplitterFilter::GetKeyFrameCount(UINT& nKFs) if(AP4_StssAtom* stss = dynamic_cast<AP4_StssAtom*>(track->GetTrakAtom()->FindChild("mdia/minf/stbl/stss")))
{
- nKFs = stss->m_Entries.ItemCount();
+ nKFs = stss->GetEntries().ItemCount();
return S_OK;
}
}
@@ -1283,7 +1226,7 @@ STDMETHODIMP CMP4SplitterFilter::GetKeyFrames(const GUID* pFormat, REFERENCE_TIM POSITION pos = m_trackpos.GetStartPosition();
while(pos)
{
- CAtlMap<DWORD, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
+ CAtlMap<AP4_Ordinal, trackpos>::CPair* pPair = m_trackpos.GetNext(pos);
AP4_Track* track = movie->GetTrack(pPair->m_key);
@@ -1294,10 +1237,10 @@ STDMETHODIMP CMP4SplitterFilter::GetKeyFrames(const GUID* pFormat, REFERENCE_TIM {
nKFs = 0;
- for(AP4_Cardinal i = 0; i < stss->m_Entries.ItemCount(); i++)
+ for(AP4_Cardinal i = 0; i < stss->GetEntries().ItemCount(); i++)
{
AP4_Sample sample;
- if(AP4_SUCCEEDED(track->GetSample(stss->m_Entries[i]-1, sample)))
+ if(AP4_SUCCEEDED(track->GetSample(stss->GetEntries()[i]-1, sample)))
pKFs[nKFs++] = 10000000i64 * sample.GetCts() / track->GetMediaTimeScale();
}
diff --git a/src/filters/parser/mp4splitter/MP4Splitter.h b/src/filters/parser/mp4splitter/MP4Splitter.h index e6effe710..d7b697439 100644 --- a/src/filters/parser/mp4splitter/MP4Splitter.h +++ b/src/filters/parser/mp4splitter/MP4Splitter.h @@ -29,8 +29,8 @@ [uuid("61F47056-E400-43d3-AF1E-AB7DFFD4C4AD")]
class CMP4SplitterFilter : public CBaseSplitterFilter
{
- struct trackpos {DWORD /*AP4_Ordinal*/ index; unsigned __int64 /*AP4_TimeStamp*/ ts;};
- CAtlMap<DWORD, trackpos> m_trackpos;
+ struct trackpos {unsigned int /*AP4_Ordinal*/ index; unsigned __int64 /*AP4_TimeStamp*/ ts;};
+ CAtlMap<unsigned int, trackpos> m_trackpos;
CSize m_framesize;
protected:
diff --git a/src/filters/parser/mp4splitter/MP4Splitter.vcproj b/src/filters/parser/mp4splitter/MP4Splitter.vcproj index 815161e4e..4218685b2 100644 --- a/src/filters/parser/mp4splitter/MP4Splitter.vcproj +++ b/src/filters/parser/mp4splitter/MP4Splitter.vcproj @@ -44,7 +44,7 @@ <Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
- AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;..\..\..\..\include;..\..\BaseClasses"
+ AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;.\AP4\Source\MetaData;..\..\..\..\include;..\..\BaseClasses"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
DisableSpecificWarnings="4812"
/>
@@ -105,7 +105,7 @@ <Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
- AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;..\..\..\..\include;..\..\BaseClasses"
+ AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;.\AP4\Source\MetaData;..\..\..\..\include;..\..\BaseClasses"
PreprocessorDefinitions="_WIN64;_DEBUG;_LIB"
DebugInformationFormat="3"
DisableSpecificWarnings="4812"
@@ -164,7 +164,7 @@ <Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
- AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;..\..\..\..\include;..\..\BaseClasses"
+ AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;.\AP4\Source\MetaData;..\..\..\..\include;..\..\BaseClasses"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
BufferSecurityCheck="true"
DisableSpecificWarnings="4812;4244"
@@ -227,7 +227,7 @@ <Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
- AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;..\..\..\..\include;..\..\BaseClasses"
+ AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;.\AP4\Source\MetaData;..\..\..\..\include;..\..\BaseClasses"
PreprocessorDefinitions="_WIN64;NDEBUG;_LIB"
BufferSecurityCheck="true"
DisableSpecificWarnings="4812"
@@ -287,7 +287,7 @@ <Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
- AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;..\..\..\..\include;..\..\BaseClasses"
+ AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;.\AP4\Source\MetaData;..\..\..\..\include;..\..\BaseClasses"
PreprocessorDefinitions="REGISTER_FILTER;WIN32;_DEBUG;_USRDLL"
DisableSpecificWarnings="4812"
/>
@@ -364,7 +364,7 @@ <Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
- AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;..\..\..\..\include;..\..\BaseClasses"
+ AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;.\AP4\Source\MetaData;..\..\..\..\include;..\..\BaseClasses"
PreprocessorDefinitions="REGISTER_FILTER;WIN32;_DEBUG;_USRDLL"
DebugInformationFormat="3"
DisableSpecificWarnings="4812"
@@ -438,7 +438,7 @@ <Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
- AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;..\..\..\..\include;..\..\BaseClasses"
+ AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;.\AP4\Source\MetaData;..\..\..\..\include;..\..\BaseClasses"
PreprocessorDefinitions="REGISTER_FILTER;WIN32;NDEBUG;_USRDLL"
BufferSecurityCheck="true"
DisableSpecificWarnings="4812"
@@ -515,7 +515,7 @@ <Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
- AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;..\..\..\..\include;..\..\BaseClasses"
+ AdditionalIncludeDirectories=".\AP4\Source\Core;.\AP4\Source\Config;.\AP4\Source\Crypto;.\AP4\Source\MetaData;..\..\..\..\include;..\..\BaseClasses"
PreprocessorDefinitions="REGISTER_FILTER;WIN32;NDEBUG;_USRDLL"
BufferSecurityCheck="true"
DisableSpecificWarnings="4812"
@@ -774,6 +774,14 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap48bdlAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap48bdlAtom.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4Array.h"
>
</File>
@@ -826,19 +834,27 @@ >
</File>
<File
- RelativePath=".\AP4\Source\Core\Ap4CmvdAtom.cpp"
+ RelativePath=".\AP4\Source\Core\Ap4Co64Atom.cpp"
>
</File>
<File
- RelativePath=".\AP4\Source\Core\Ap4CmvdAtom.h"
+ RelativePath=".\AP4\Source\Core\Ap4Co64Atom.h"
>
</File>
<File
- RelativePath=".\AP4\Source\Core\Ap4Co64Atom.cpp"
+ RelativePath=".\AP4\Source\Core\Ap4Command.cpp"
>
</File>
<File
- RelativePath=".\AP4\Source\Core\Ap4Co64Atom.h"
+ RelativePath=".\AP4\Source\Core\Ap4Command.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4CommandFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4CommandFactory.h"
>
</File>
<File
@@ -862,10 +878,6 @@ >
</File>
<File
- RelativePath=".\AP4\Source\Core\Ap4DataAtom.cpp"
- >
- </File>
- <File
RelativePath=".\AP4\Source\Core\Ap4DataAtom.h"
>
</File>
@@ -878,14 +890,6 @@ >
</File>
<File
- RelativePath=".\AP4\Source\Core\Ap4DcomAtom.cpp"
- >
- </File>
- <File
- RelativePath=".\AP4\Source\Core\Ap4DcomAtom.h"
- >
- </File>
- <File
RelativePath=".\AP4\Source\Core\Ap4Debug.cpp"
>
</File>
@@ -934,6 +938,18 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4DynamicCast.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4ElstAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4ElstAtom.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4EsDescriptor.cpp"
>
</File>
@@ -950,6 +966,14 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4Expandable.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4Expandable.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4File.cpp"
>
</File>
@@ -962,6 +986,14 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4FileCopier.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4FileCopier.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4FileWriter.cpp"
>
</File>
@@ -994,6 +1026,14 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4GrpiAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4GrpiAtom.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4HdlrAtom.cpp"
>
</File>
@@ -1030,6 +1070,30 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4IodsAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4IodsAtom.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4Ipmp.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4Ipmp.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4IproAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4IproAtom.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4IsfmAtom.cpp"
>
</File>
@@ -1038,6 +1102,14 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4IsltAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4IsltAtom.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4IsmaCryp.cpp"
>
</File>
@@ -1050,6 +1122,14 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4Marlin.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4Marlin.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4MdhdAtom.cpp"
>
</File>
@@ -1058,6 +1138,14 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4MfhdAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4MfhdAtom.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4MoovAtom.cpp"
>
</File>
@@ -1090,6 +1178,54 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4ObjectDescriptor.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4ObjectDescriptor.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OdafAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OdafAtom.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OddaAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OddaAtom.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OdheAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OdheAtom.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OhdrAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OhdrAtom.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OmaDcf.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4OmaDcf.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4Processor.cpp"
>
</File>
@@ -1098,6 +1234,18 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4Protection.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4Protection.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4Results.cpp"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4Results.h"
>
</File>
@@ -1190,6 +1338,14 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4String.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4String.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4StscAtom.cpp"
>
</File>
@@ -1238,6 +1394,14 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4TfhdAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4TfhdAtom.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4TimsAtom.cpp"
>
</File>
@@ -1278,15 +1442,15 @@ >
</File>
<File
- RelativePath=".\AP4\Source\Core\Ap4Types.h"
+ RelativePath=".\AP4\Source\Core\Ap4TrunAtom.cpp"
>
</File>
<File
- RelativePath=".\AP4\Source\Core\Ap4UnknownDescriptor.cpp"
+ RelativePath=".\AP4\Source\Core\Ap4TrunAtom.h"
>
</File>
<File
- RelativePath=".\AP4\Source\Core\Ap4UnknownDescriptor.h"
+ RelativePath=".\AP4\Source\Core\Ap4Types.h"
>
</File>
<File
@@ -1306,6 +1470,18 @@ >
</File>
<File
+ RelativePath=".\AP4\Source\Core\Ap4UuidAtom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4UuidAtom.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\Core\Ap4Version.h"
+ >
+ </File>
+ <File
RelativePath=".\AP4\Source\Core\Ap4VmhdAtom.cpp"
>
</File>
@@ -1342,6 +1518,18 @@ >
</File>
</Filter>
+ <Filter
+ Name="MetaData"
+ >
+ <File
+ RelativePath=".\AP4\Source\MetaData\Ap4MetaData.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\AP4\Source\MetaData\Ap4MetaData.h"
+ >
+ </File>
+ </Filter>
</Filter>
</Files>
<Globals>
|