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

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorv0lt <v0lt@users.sourceforge.net>2012-01-21 00:47:31 +0400
committerv0lt <v0lt@users.sourceforge.net>2012-01-21 00:47:31 +0400
commit06be523250128e222f4351d99cbdb1e94ee3622f (patch)
tree17b4e7bc48180cc9ae15c72e417dc974ac9d9a69 /src/filters/parser/MP4Splitter/AP4
parent77efede83c2eea37d111af31cfb2eb32515faa24 (diff)
MP4Splitter: added support for 'lpcm' in mov. partial update for bento4 (ticket #1962)
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@3984 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/parser/MP4Splitter/AP4')
-rw-r--r--src/filters/parser/MP4Splitter/AP4/Core/Ap4Atom.h2
-rw-r--r--src/filters/parser/MP4Splitter/AP4/Core/Ap4AtomFactory.cpp1
-rw-r--r--src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.cpp22
-rw-r--r--src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.h1
-rw-r--r--src/filters/parser/MP4Splitter/AP4/Core/Ap4EndaAtom.h2
-rw-r--r--src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.cpp232
-rw-r--r--src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.h93
-rw-r--r--src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.cpp13
-rw-r--r--src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.h1
9 files changed, 242 insertions, 125 deletions
diff --git a/src/filters/parser/MP4Splitter/AP4/Core/Ap4Atom.h b/src/filters/parser/MP4Splitter/AP4/Core/Ap4Atom.h
index 7cd44e2a6..8c86192b6 100644
--- a/src/filters/parser/MP4Splitter/AP4/Core/Ap4Atom.h
+++ b/src/filters/parser/MP4Splitter/AP4/Core/Ap4Atom.h
@@ -260,6 +260,8 @@ const AP4_Atom::Type AP4_ATOM_TYPE_IN24 = AP4_ATOM_TYPE('i','n','2','4');
const AP4_Atom::Type AP4_ATOM_TYPE_IN32 = AP4_ATOM_TYPE('i','n','3','2');
const AP4_Atom::Type AP4_ATOM_TYPE_FL32 = AP4_ATOM_TYPE('f','l','3','2');
const AP4_Atom::Type AP4_ATOM_TYPE_FL64 = AP4_ATOM_TYPE('f','l','6','4');
+//LPCM
+const AP4_Atom::Type AP4_ATOM_TYPE_LPCM = AP4_ATOM_TYPE('l','p','c','m');
//
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');
diff --git a/src/filters/parser/MP4Splitter/AP4/Core/Ap4AtomFactory.cpp b/src/filters/parser/MP4Splitter/AP4/Core/Ap4AtomFactory.cpp
index daeafbb3b..38e0f02e3 100644
--- a/src/filters/parser/MP4Splitter/AP4/Core/Ap4AtomFactory.cpp
+++ b/src/filters/parser/MP4Splitter/AP4/Core/Ap4AtomFactory.cpp
@@ -424,6 +424,7 @@ AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream,
case AP4_ATOM_TYPE_IN32:
case AP4_ATOM_TYPE_FL32:
case AP4_ATOM_TYPE_FL64:
+ case AP4_ATOM_TYPE_LPCM:
case AP4_ATOM_TYPE_ALAW:
case AP4_ATOM_TYPE_ULAW:
case AP4_ATOM_TYPE_NMOS:
diff --git a/src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.cpp b/src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.cpp
index 0385c3a7b..d0637a9eb 100644
--- a/src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.cpp
+++ b/src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.cpp
@@ -145,6 +145,28 @@ AP4_ByteStream::ReadUI64(AP4_UI64& value)
}
/*----------------------------------------------------------------------
+| 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
diff --git a/src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.h b/src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.h
index 2e0e99deb..9ba839c64 100644
--- a/src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.h
+++ b/src/filters/parser/MP4Splitter/AP4/Core/Ap4ByteStream.h
@@ -46,6 +46,7 @@ class AP4_ByteStream : public AP4_Referenceable
virtual AP4_Result Read(void* buffer,
AP4_Size bytes_to_read,
AP4_Size* bytes_read = 0) = 0;
+ virtual AP4_Result ReadDouble(double& value);
virtual AP4_Result ReadUI64(AP4_UI64& value);
virtual AP4_Result ReadUI32(AP4_UI32& value);
virtual AP4_Result ReadUI24(AP4_UI32& value);
diff --git a/src/filters/parser/MP4Splitter/AP4/Core/Ap4EndaAtom.h b/src/filters/parser/MP4Splitter/AP4/Core/Ap4EndaAtom.h
index 8f673be5f..d6ee3dee4 100644
--- a/src/filters/parser/MP4Splitter/AP4/Core/Ap4EndaAtom.h
+++ b/src/filters/parser/MP4Splitter/AP4/Core/Ap4EndaAtom.h
@@ -24,7 +24,7 @@ public:
AP4_Result WriteFields(AP4_ByteStream& stream) { return AP4_FAILURE; }
- AP4_Atom::Type IsLittleEndian() const { return m_LittleEndian; }
+ AP4_Atom::Type ReadEndian() const { return m_LittleEndian; }
private:
AP4_UI16 m_LittleEndian;
diff --git a/src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.cpp b/src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.cpp
index 957b9cc3c..f89f587f4 100644
--- a/src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.cpp
+++ b/src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.cpp
@@ -308,12 +308,29 @@ AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format,
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_QtVersion(0),
+ m_QtRevision(0),
+ m_QtVendor(0),
m_ChannelCount(channel_count),
- m_SampleSize(sample_size)
+ 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),
+// mpc-hc custom code start
+ m_Endian(ENDIAN_NOTSET)
+// mpc-hc custom code end
{
m_Size += 20;
}
@@ -330,17 +347,9 @@ AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format,
// read fields
ReadFields(stream);
- /////////////////////////////////////////////////////////////////////////////////////////////////
- //hack to support the formats using more than 16 bits per sample
- //in the future will have to be moved to MP4Splitter.cpp
- if(m_DescriptionVersion == 1 && m_SampleSize == 16){
- //QuickTime File Format Specification->Sound Sample Description (Version 1)->Bytes per packet
- m_SampleSize = m_BytesPerPacket * 8;
- }
- //
//hack to get the correct WAVEFORMATEX in MP4Splitter.cpp
//need more information about audio formats used in older movs (QuickTime 2.x).
- if(m_DescriptionVersion == 0)
+ if(m_QtVersion == 0)
{
switch( format )
{
@@ -348,33 +357,33 @@ AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format,
case AP4_ATOM_TYPE_RAW:
case AP4_ATOM_TYPE_TWOS:
case AP4_ATOM_TYPE_SOWT:
- m_SamplesPerPacket = 1;
- m_BytesPerPacket = m_SampleSize / 8;
- m_BytesPerFrame = m_ChannelCount * m_BytesPerPacket;
- m_BytesPerSample = m_SampleSize/8;
+ m_QtV1SamplesPerPacket = 1;
+ m_QtV1BytesPerPacket = m_SampleSize / 8;
+ m_QtV1BytesPerFrame = m_ChannelCount * m_QtV1BytesPerPacket;
+ m_QtV1BytesPerSample = m_SampleSize/8;
break;
case AP4_ATOM_TYPE_IMA4:
- m_SamplesPerPacket = 64;
- m_BytesPerPacket = 34;
- m_BytesPerFrame = m_ChannelCount * m_BytesPerPacket;
- m_BytesPerSample = m_SampleSize/8;
+ m_QtV1SamplesPerPacket = 64;
+ m_QtV1BytesPerPacket = 34;
+ m_QtV1BytesPerFrame = m_ChannelCount * m_QtV1BytesPerPacket;
+ m_QtV1BytesPerSample = m_SampleSize/8;
break;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
- // must be called after m_DescriptionVersion was already set
+ // must be called after m_QtVersion 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);
// read AP4_ATOM_TYPE_ENDA
- m_LittleEndian = 0xffff;
+ m_Endian = ENDIAN_NOTSET;
if(AP4_Atom* child = GetChild(AP4_ATOM_TYPE_WAVE))
if(AP4_ContainerAtom* wave = dynamic_cast<AP4_ContainerAtom*>(child))
if (AP4_EndaAtom* endian = dynamic_cast<AP4_EndaAtom*>(wave->GetChild(AP4_ATOM_TYPE_ENDA)))
- m_LittleEndian = endian->IsLittleEndian();
+ m_Endian = endian->ReadEndian();
}
/*----------------------------------------------------------------------
@@ -385,18 +394,51 @@ AP4_AudioSampleEntry::AP4_AudioSampleEntry(AP4_Atom::Type format,
AP4_MpegSampleEntry(format, size)
{
}
-
+
/*----------------------------------------------------------------------
-| AP4_AudioSampleEntry::GetFieldsSize
+| AP4_AudioSampleEntry::GetFieldsSize
+---------------------------------------------------------------------*/
AP4_Size
AP4_AudioSampleEntry::GetFieldsSize()
{
- return AP4_SampleEntry::GetFieldsSize() + 20 + (m_DescriptionVersion == 1 ? 16 : 0);
+ 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::ReadFields
+| 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)
@@ -406,68 +448,54 @@ AP4_AudioSampleEntry::ReadFields(AP4_ByteStream& 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;
- }
-
+ 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;
}
@@ -483,11 +511,11 @@ AP4_AudioSampleEntry::WriteFields(AP4_ByteStream& stream)
result = AP4_SampleEntry::WriteFields(stream);
//
- result = stream.WriteUI16(m_DescriptionVersion);
+ result = stream.WriteUI16(m_QtVersion);
if (AP4_FAILED(result)) return result;
- result = stream.WriteUI16(m_RevisionLevel);
+ result = stream.WriteUI16(m_QtRevision);
if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_Vendor);
+ result = stream.WriteUI32(m_QtVendor);
if (AP4_FAILED(result)) return result;
// channel count
@@ -499,29 +527,29 @@ AP4_AudioSampleEntry::WriteFields(AP4_ByteStream& stream)
if (AP4_FAILED(result)) return result;
// predefined1
- result = stream.WriteUI16(m_CompressionID);
+ result = stream.WriteUI16(m_QtCompressionId);
if (AP4_FAILED(result)) return result;
// reserved3
- result = stream.WriteUI16(m_PacketSize);
+ 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_DescriptionVersion == 1)
+ if(m_QtVersion == 1)
{
- result = stream.WriteUI32(m_SamplesPerPacket);
+ result = stream.WriteUI32(m_QtV1SamplesPerPacket);
if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_BytesPerPacket);
+ result = stream.WriteUI32(m_QtV1BytesPerPacket);
if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_BytesPerFrame);
+ result = stream.WriteUI32(m_QtV1BytesPerFrame);
if (AP4_FAILED(result)) return result;
- result = stream.WriteUI32(m_BytesPerSample);
+ result = stream.WriteUI32(m_QtV1BytesPerSample);
if (AP4_FAILED(result)) return result;
}
- else if(m_DescriptionVersion != 0)
+ else if(m_QtVersion != 0)
{
return AP4_FAILURE;
}
diff --git a/src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.h b/src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.h
index 9e8cfe732..4e60c862c 100644
--- a/src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.h
+++ b/src/filters/parser/MP4Splitter/AP4/Core/Ap4SampleEntry.h
@@ -136,14 +136,52 @@ class AP4_AudioSampleEntry : public AP4_MpegSampleEntry
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; }
- AP4_UI16 IsLittleEndian() { return m_LittleEndian; }
+ AP4_UI32 GetSampleRate();
+// AP4_UI16 GetSampleSize() { return m_SampleSize; }
+ AP4_UI16 GetChannelCount();
+// mpc-hc custom code start
+ AP4_UI32 GetSamplesPerPacket()
+ {
+ if (m_QtVersion == 2) {
+ return m_QtV2LPCMFramesPerAudioPacket;
+ }
+ return m_QtV1SamplesPerPacket;
+ }
+ AP4_UI32 GetBytesPerFrame()
+ {
+ if (m_QtVersion == 2) {
+ return m_QtV2BytesPerAudioPacket;
+ }
+ return m_QtV1BytesPerFrame;
+ }
+ AP4_UI16 GetSampleSize()
+ {
+ if (m_QtVersion == 1 && m_SampleSize == 16) {
+ //QuickTime File Format Specification->Sound Sample Description (Version 1)->Bytes per packet
+ return m_QtV1BytesPerPacket * 8;
+ } else if (m_QtVersion == 2) {
+ return m_QtV2BitsPerChannel;
+ }
+ return m_SampleSize;
+ }
+ AP4_UI16 GetEndian()
+ {
+ /*if (m_QtVersion == 2) {
+ if (m_QtV2FormatSpecificFlags & 2) {
+ return ENDIAN_BIG;
+ } else {
+ return ENDIAN_LITTLE;
+ }
+ }*/
+ return m_Endian;
+ }
+ AP4_UI32 GetFormatSpecificFlags() { return m_QtV2FormatSpecificFlags; }
+
+#define ENDIAN_NOTSET -1
+#define ENDIAN_BIG 0
+#define ENDIAN_LITTLE 1
+
+// mpc-hc custom code end
// methods
AP4_SampleDescription* ToSampleDescription();
@@ -156,21 +194,32 @@ protected:
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_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
+ // Version == 1
+ AP4_UI32 m_QtV1SamplesPerPacket;
+ AP4_UI32 m_QtV1BytesPerPacket;
+ AP4_UI32 m_QtV1BytesPerFrame;
+ AP4_UI32 m_QtV1BytesPerSample;
+ // Version == 2
+ 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;
// from 'enda' atom
- AP4_UI16 m_LittleEndian;
+ AP4_UI16 m_Endian;
+
};
/*----------------------------------------------------------------------
diff --git a/src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.cpp b/src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.cpp
index 29f208d00..43bb44e14 100644
--- a/src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.cpp
+++ b/src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.cpp
@@ -33,6 +33,19 @@
#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
+---------------------------------------------------------------------*/
unsigned long long
diff --git a/src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.h b/src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.h
index 9943fe18a..885d37a86 100644
--- a/src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.h
+++ b/src/filters/parser/MP4Splitter/AP4/Core/Ap4Utils.h
@@ -45,6 +45,7 @@
/*----------------------------------------------------------------------
| byte I/O
+---------------------------------------------------------------------*/
+double AP4_BytesToDoubleBE(const unsigned char* bytes);
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);