blob: a818c77343e0e78402f85be511ef0236a41f0c41 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/formats/mp4/dtsx.h"
#include "base/logging.h"
#include "media/base/bit_reader.h"
#include "media/formats/mp4/rcheck.h"
namespace media {
namespace mp4 {
DTSX::DTSX() = default;
DTSX::DTSX(const DTSX& other) = default;
DTSX::~DTSX() = default;
bool DTSX::Parse(const std::vector<uint8_t>& data, MediaLog* media_log) {
if (data.empty())
return false;
if (data.size() < (2 + 3 + 5 + 32 + 1 + 2 + 8) / 8)
return false;
DVLOG(3) << "dtsx data.size " << data.size();
// Parse udts box using reader.
BitReader reader(&data[0], data.size());
// Read DecoderProfileCode
RCHECK(reader.ReadBits(6, &decoder_profile_code_));
// Read FrameDurationCode
uint8_t frame_duration_code = 0;
RCHECK(reader.ReadBits(2, &frame_duration_code));
switch (frame_duration_code) {
case 0:
frame_duration_ = 512;
break;
case 1:
frame_duration_ = 1024;
break;
case 2:
frame_duration_ = 2048;
break;
case 3:
frame_duration_ = 4096;
break;
default:
frame_duration_ = 0;
break;
}
// Read MaxPayloadCode
uint8_t max_payload_code = 0;
RCHECK(reader.ReadBits(3, &max_payload_code));
switch (max_payload_code) {
case 0:
max_payload_ = 2048;
break;
case 1:
max_payload_ = 4096;
break;
case 2:
max_payload_ = 8192;
break;
case 3:
max_payload_ = 16384;
break;
case 4:
max_payload_ = 32768;
break;
case 5:
max_payload_ = 65536;
break;
case 6:
max_payload_ = 131072;
break;
case 7:
default:
max_payload_ = 0;
break;
}
// Read NumPresentationsCode
RCHECK(reader.ReadBits(5, &num_presentations_));
// Read ChannelMask
RCHECK(reader.ReadBits(32, &channel_mask_));
// Read BaseSamplingFrequencyCode
int base_sampling_frequency = 0;
uint8_t base_sampling_frequency_code = 0;
RCHECK(reader.ReadBits(1, &base_sampling_frequency_code));
if (base_sampling_frequency_code == 1)
base_sampling_frequency = 48000;
else
base_sampling_frequency = 44100;
// Read SampleRateMod
int sample_rate_mod = 0;
uint8_t sample_rate_mod_code;
RCHECK(reader.ReadBits(2, &sample_rate_mod_code));
switch (sample_rate_mod) {
case 0:
sample_rate_mod = 1;
break;
case 1:
sample_rate_mod = 2;
break;
case 2:
sample_rate_mod = 4;
break;
case 3:
sample_rate_mod = 8;
break;
default:
// error, should not hit default case.
DLOG(ERROR) << "SampleRateMod invalid value";
return false;
}
// Calculate the Sampling Frequency
sampling_frequency_ = base_sampling_frequency * sample_rate_mod;
LogDtsxParameters();
return true;
}
uint8_t DTSX::GetDecoderProfileCode() const {
return decoder_profile_code_;
}
int DTSX::GetFrameDuration() const {
return frame_duration_;
}
int DTSX::GetMaxPayload() const {
return max_payload_;
}
int DTSX::GetNumPresentations() const {
return num_presentations_;
}
uint32_t DTSX::GetChannelMask() const {
return channel_mask_;
}
int DTSX::GetSamplingFrequency() const {
return sampling_frequency_;
}
void DTSX::LogDtsxParameters() {
DVLOG(3) << "DecoderProfileCode " << static_cast<int>(decoder_profile_code_)
<< "Frame Duration " << frame_duration_ << "Max Payload "
<< max_payload_ << "Num Presentations " << num_presentations_
<< "Channel Mask " << channel_mask_ << "Sampling Frequency "
<< sampling_frequency_;
}
} // namespace mp4
} // namespace media