141 lines
2.9 KiB
C++
141 lines
2.9 KiB
C++
#include "audiotrack.hpp"
|
|
#include "cluster.hpp"
|
|
#include "segment.hpp"
|
|
#include "ebmlreadhelpers.hpp"
|
|
#include "imkvreader.hpp"
|
|
#include "block.hpp"
|
|
#include "mkvprofiler.hpp"
|
|
|
|
#include <assert.h>
|
|
|
|
namespace mkvparser
|
|
{
|
|
|
|
AudioTrack::AudioTrack(
|
|
Segment* pSegment,
|
|
long long element_start,
|
|
long long element_size)
|
|
: Track(pSegment, element_start, element_size)
|
|
, m_rate(8000.0)
|
|
, m_channels(1)
|
|
, m_bitDepth(0)
|
|
{
|
|
}
|
|
|
|
|
|
long AudioTrack::Parse(
|
|
Segment* pSegment,
|
|
const Info& info,
|
|
long long element_start,
|
|
long long element_size,
|
|
AudioTrack*& pResult)
|
|
{
|
|
PROFILER_SCOPED_EVENT("webm::AudioTrack::Parse");
|
|
|
|
if (pResult)
|
|
return -1;
|
|
|
|
if (info.type != Track::kAudio)
|
|
return -1;
|
|
|
|
IMkvReader* const pReader = pSegment->GetReader();
|
|
|
|
const Settings& s = info.settings;
|
|
assert(s.start >= 0);
|
|
assert(s.size >= 0);
|
|
|
|
long long pos = s.start;
|
|
assert(pos >= 0);
|
|
|
|
const long long stop = pos + s.size;
|
|
|
|
double rate = 8000.0; // MKV default
|
|
long long channels = 1;
|
|
long long bit_depth = 0;
|
|
|
|
while (pos < stop)
|
|
{
|
|
long long id, size;
|
|
|
|
long status = ParseElementHeader(
|
|
pReader,
|
|
pos,
|
|
stop,
|
|
id,
|
|
size);
|
|
|
|
if (status < 0) //error
|
|
return status;
|
|
|
|
if (id == 0x35) //Sample Rate
|
|
{
|
|
status = UnserializeFloat(pReader, pos, size, rate);
|
|
|
|
if (status < 0)
|
|
return status;
|
|
|
|
if (rate <= 0)
|
|
return E_FILE_FORMAT_INVALID;
|
|
}
|
|
else if (id == 0x1F) //Channel Count
|
|
{
|
|
channels = UnserializeUInt(pReader, pos, size);
|
|
|
|
if (channels <= 0)
|
|
return E_FILE_FORMAT_INVALID;
|
|
}
|
|
else if (id == 0x2264) //Bit Depth
|
|
{
|
|
bit_depth = UnserializeUInt(pReader, pos, size);
|
|
|
|
if (bit_depth <= 0)
|
|
return E_FILE_FORMAT_INVALID;
|
|
}
|
|
|
|
pos += size; //consume payload
|
|
assert(pos <= stop);
|
|
}
|
|
|
|
assert(pos == stop);
|
|
|
|
AudioTrack* const pTrack = new AudioTrack(pSegment,
|
|
element_start,
|
|
element_size);
|
|
|
|
if (pTrack == NULL)
|
|
return -1; //generic error
|
|
|
|
const int status = info.Copy(pTrack->m_info);
|
|
|
|
if (status)
|
|
{
|
|
delete pTrack;
|
|
return status;
|
|
}
|
|
|
|
pTrack->m_rate = rate;
|
|
pTrack->m_channels = channels;
|
|
pTrack->m_bitDepth = bit_depth;
|
|
|
|
pResult = pTrack;
|
|
return 0; //success
|
|
}
|
|
|
|
|
|
double AudioTrack::GetSamplingRate() const
|
|
{
|
|
return m_rate;
|
|
}
|
|
|
|
|
|
long long AudioTrack::GetChannels() const
|
|
{
|
|
return m_channels;
|
|
}
|
|
|
|
long long AudioTrack::GetBitDepth() const
|
|
{
|
|
return m_bitDepth;
|
|
}
|
|
|
|
} // namespace mkvparser
|