LibMedia: Rename timing getters in AudioBlock
This new naming will make timescale modifications more comprehensible.
This commit is contained in:
parent
c8c64e4819
commit
9ca1db3bb8
6 changed files with 32 additions and 32 deletions
|
|
@ -19,10 +19,10 @@ namespace Media {
|
||||||
class AudioBlock {
|
class AudioBlock {
|
||||||
public:
|
public:
|
||||||
Audio::SampleSpecification const& sample_specification() const { return m_sample_specification; }
|
Audio::SampleSpecification const& sample_specification() const { return m_sample_specification; }
|
||||||
AK::Duration timestamp() const { return m_timestamp; }
|
AK::Duration media_time_start() const { return m_media_time_start; }
|
||||||
i64 timestamp_in_frames() const { return m_timestamp_in_frames; }
|
AK::Duration media_time_end() const { return AK::Duration::from_time_units(end_frame_index(), 1, sample_rate()); }
|
||||||
i64 end_timestamp_in_frames() const { return saturating_add(m_timestamp_in_frames, AK::clamp_to<i64>(frame_count())); }
|
i64 first_frame_index() const { return m_first_frame_index; }
|
||||||
AK::Duration end_timestamp() const { return AK::Duration::from_time_units(end_timestamp_in_frames(), 1, sample_rate()); }
|
i64 end_frame_index() const { return saturating_add(m_first_frame_index, AK::clamp_to<i64>(frame_count())); }
|
||||||
Span<float> channel_data(size_t channel)
|
Span<float> channel_data(size_t channel)
|
||||||
{
|
{
|
||||||
VERIFY(channel < channel_count());
|
VERIFY(channel < channel_count());
|
||||||
|
|
@ -45,29 +45,29 @@ public:
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
m_sample_specification = {};
|
m_sample_specification = {};
|
||||||
m_timestamp = {};
|
m_media_time_start = {};
|
||||||
m_timestamp_in_frames = 0;
|
m_first_frame_index = 0;
|
||||||
m_frame_count = 0;
|
m_frame_count = 0;
|
||||||
}
|
}
|
||||||
void initialize(Audio::SampleSpecification sample_specification, AK::Duration timestamp, size_t frame_count)
|
void initialize(Audio::SampleSpecification sample_specification, AK::Duration media_time_start, size_t frame_count)
|
||||||
{
|
{
|
||||||
VERIFY(sample_specification.is_valid());
|
VERIFY(sample_specification.is_valid());
|
||||||
VERIFY(frame_count <= NumericLimits<i64>::max());
|
VERIFY(frame_count <= NumericLimits<i64>::max());
|
||||||
VERIFY(!Checked<size_t>::multiplication_would_overflow(frame_count, sample_specification.channel_count()));
|
VERIFY(!Checked<size_t>::multiplication_would_overflow(frame_count, sample_specification.channel_count()));
|
||||||
m_sample_specification = sample_specification;
|
m_sample_specification = sample_specification;
|
||||||
m_timestamp = timestamp;
|
m_media_time_start = media_time_start;
|
||||||
m_timestamp_in_frames = timestamp.to_time_units(1, sample_rate());
|
m_first_frame_index = media_time_start.to_time_units(1, sample_rate());
|
||||||
m_frame_count = frame_count;
|
m_frame_count = frame_count;
|
||||||
ensure_frame_capacity(frame_count);
|
ensure_frame_capacity(frame_count);
|
||||||
}
|
}
|
||||||
void initialize(Audio::SampleSpecification sample_specification, i64 timestamp_in_frames, size_t frame_count)
|
void initialize(Audio::SampleSpecification sample_specification, i64 first_frame_index, size_t frame_count)
|
||||||
{
|
{
|
||||||
VERIFY(sample_specification.is_valid());
|
VERIFY(sample_specification.is_valid());
|
||||||
VERIFY(frame_count <= NumericLimits<i64>::max());
|
VERIFY(frame_count <= NumericLimits<i64>::max());
|
||||||
VERIFY(!Checked<size_t>::multiplication_would_overflow(frame_count, sample_specification.channel_count()));
|
VERIFY(!Checked<size_t>::multiplication_would_overflow(frame_count, sample_specification.channel_count()));
|
||||||
m_sample_specification = sample_specification;
|
m_sample_specification = sample_specification;
|
||||||
m_timestamp_in_frames = timestamp_in_frames;
|
m_first_frame_index = first_frame_index;
|
||||||
m_timestamp = AK::Duration::from_time_units(timestamp_in_frames, 1, sample_rate());
|
m_media_time_start = AK::Duration::from_time_units(first_frame_index, 1, sample_rate());
|
||||||
m_frame_count = frame_count;
|
m_frame_count = frame_count;
|
||||||
ensure_frame_capacity(frame_count);
|
ensure_frame_capacity(frame_count);
|
||||||
}
|
}
|
||||||
|
|
@ -98,11 +98,11 @@ public:
|
||||||
{
|
{
|
||||||
return sample_specification().sample_rate();
|
return sample_specification().sample_rate();
|
||||||
}
|
}
|
||||||
void set_timestamp_in_frames(i64 timestamp_in_frames)
|
void set_first_frame_index(i64 first_frame_index)
|
||||||
{
|
{
|
||||||
VERIFY(!is_empty());
|
VERIFY(!is_empty());
|
||||||
m_timestamp_in_frames = timestamp_in_frames;
|
m_first_frame_index = first_frame_index;
|
||||||
m_timestamp = AK::Duration::from_time_units(timestamp_in_frames, 1, sample_rate());
|
m_media_time_start = AK::Duration::from_time_units(first_frame_index, 1, sample_rate());
|
||||||
}
|
}
|
||||||
bool is_empty() const
|
bool is_empty() const
|
||||||
{
|
{
|
||||||
|
|
@ -138,8 +138,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
Audio::SampleSpecification m_sample_specification;
|
Audio::SampleSpecification m_sample_specification;
|
||||||
AK::Duration m_timestamp;
|
AK::Duration m_media_time_start;
|
||||||
i64 m_timestamp_in_frames { 0 };
|
i64 m_first_frame_index { 0 };
|
||||||
size_t m_frame_count { 0 };
|
size_t m_frame_count { 0 };
|
||||||
FixedArray<float> m_data;
|
FixedArray<float> m_data;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ ErrorOr<void> FFmpegAudioConverter::convert(AudioBlock& input)
|
||||||
VERIFY(converted_frames_result <= m_output_buffer_frame_count);
|
VERIFY(converted_frames_result <= m_output_buffer_frame_count);
|
||||||
auto converted_frames = static_cast<size_t>(converted_frames_result);
|
auto converted_frames = static_cast<size_t>(converted_frames_result);
|
||||||
|
|
||||||
input.initialize(m_output_sample_specification, input.timestamp(), converted_frames);
|
input.initialize(m_output_sample_specification, input.media_time_start(), converted_frames);
|
||||||
for (size_t channel = 0; channel < output_channel_count; channel++)
|
for (size_t channel = 0; channel < output_channel_count; channel++)
|
||||||
AK::TypedTransfer<float>::copy(input.channel_data(channel).data(), reinterpret_cast<float*>(m_output_buffers[channel]), converted_frames);
|
AK::TypedTransfer<float>::copy(input.channel_data(channel).data(), reinterpret_cast<float*>(m_output_buffers[channel]), converted_frames);
|
||||||
return {};
|
return {};
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ PipelineStatus AudioMixer::combined_input_status() const
|
||||||
for (auto& [input, input_data] : m_inputs) {
|
for (auto& [input, input_data] : m_inputs) {
|
||||||
if (!input_data.current_block.is_empty()
|
if (!input_data.current_block.is_empty()
|
||||||
&& input_data.current_block.sample_specification() == m_sample_specification
|
&& input_data.current_block.sample_specification() == m_sample_specification
|
||||||
&& input_data.current_block.end_timestamp_in_frames() > m_next_frame_to_write) {
|
&& input_data.current_block.end_frame_index() > m_next_frame_to_write) {
|
||||||
status = select_combined_pipeline_status(status, PipelineStatus::HaveData);
|
status = select_combined_pipeline_status(status, PipelineStatus::HaveData);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -270,7 +270,7 @@ void AudioMixer::pull(AudioBlock& into)
|
||||||
return false;
|
return false;
|
||||||
if (current_block.sample_specification() != m_sample_specification)
|
if (current_block.sample_specification() != m_sample_specification)
|
||||||
return false;
|
return false;
|
||||||
if (current_block.end_timestamp_in_frames() <= input_data.next_frame)
|
if (current_block.end_frame_index() <= input_data.next_frame)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}();
|
}();
|
||||||
|
|
@ -288,7 +288,7 @@ void AudioMixer::pull(AudioBlock& into)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto first_frame_offset = current_block.timestamp_in_frames();
|
auto first_frame_offset = current_block.first_frame_index();
|
||||||
if (first_frame_offset >= frames_end_cap) {
|
if (first_frame_offset >= frames_end_cap) {
|
||||||
input_data.next_frame = frames_end_cap;
|
input_data.next_frame = frames_end_cap;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ void DecodedAudioProducer::ThreadData::pull(AudioBlock& into)
|
||||||
}
|
}
|
||||||
if (!m_queue.is_empty()) {
|
if (!m_queue.is_empty()) {
|
||||||
into = m_queue.dequeue();
|
into = m_queue.dequeue();
|
||||||
m_earliest_available_timestamp = into.end_timestamp();
|
m_earliest_available_timestamp = into.media_time_end();
|
||||||
wake();
|
wake();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -350,7 +350,7 @@ void DecodedAudioProducer::ThreadData::invoke_on_main_thread(Invokee invokee)
|
||||||
|
|
||||||
void DecodedAudioProducer::ThreadData::dispatch_block_end_time(AudioBlock const& block)
|
void DecodedAudioProducer::ThreadData::dispatch_block_end_time(AudioBlock const& block)
|
||||||
{
|
{
|
||||||
auto end_time = block.end_timestamp();
|
auto end_time = block.media_time_end();
|
||||||
if (end_time < m_duration)
|
if (end_time < m_duration)
|
||||||
return;
|
return;
|
||||||
m_duration = end_time;
|
m_duration = end_time;
|
||||||
|
|
@ -368,7 +368,7 @@ void DecodedAudioProducer::ThreadData::queue_block(AudioBlock&& block)
|
||||||
if (m_seek_id.load() != m_last_processed_seek_id)
|
if (m_seek_id.load() != m_last_processed_seek_id)
|
||||||
return;
|
return;
|
||||||
dispatch_block_end_time(block);
|
dispatch_block_end_time(block);
|
||||||
m_latest_available_timestamp = block.end_timestamp();
|
m_latest_available_timestamp = block.media_time_end();
|
||||||
m_queue.enqueue(move(block));
|
m_queue.enqueue(move(block));
|
||||||
VERIFY(!m_queue.tail().is_empty());
|
VERIFY(!m_queue.tail().is_empty());
|
||||||
dispatch_wake_if_needed_while_locked();
|
dispatch_wake_if_needed_while_locked();
|
||||||
|
|
@ -396,9 +396,9 @@ DecoderErrorOr<void> DecodedAudioProducer::ThreadData::retrieve_next_block(Audio
|
||||||
if (convert_result.is_error())
|
if (convert_result.is_error())
|
||||||
return DecoderError::format(DecoderErrorCategory::NotImplemented, "Sample specification conversion failed: {}", convert_result.error().string_literal());
|
return DecoderError::format(DecoderErrorCategory::NotImplemented, "Sample specification conversion failed: {}", convert_result.error().string_literal());
|
||||||
|
|
||||||
if (block.timestamp_in_frames() < m_last_output_frame)
|
if (block.first_frame_index() < m_last_output_frame)
|
||||||
block.set_timestamp_in_frames(m_last_output_frame);
|
block.set_first_frame_index(m_last_output_frame);
|
||||||
m_last_output_frame = block.end_timestamp_in_frames();
|
m_last_output_frame = block.end_frame_index();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -493,7 +493,7 @@ bool DecodedAudioProducer::ThreadData::handle_seek()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_block.timestamp() > timestamp) {
|
if (current_block.media_time_start() > timestamp) {
|
||||||
auto locker = take_lock();
|
auto locker = take_lock();
|
||||||
resolve_seek(seek_id, moved_position);
|
resolve_seek(seek_id, moved_position);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ ErrorOr<NonnullRefPtr<AudioPlaybackSink>> AudioPlaybackSink::try_create(Pipeline
|
||||||
output_thread_data->m_playback_stream->notify_data_available();
|
output_thread_data->m_playback_stream->notify_data_available();
|
||||||
|
|
||||||
if (status == PipelineStatus::HaveData)
|
if (status == PipelineStatus::HaveData)
|
||||||
output_thread_data->m_last_real_data_end_in_frames = output_block.end_timestamp_in_frames();
|
output_thread_data->m_last_real_data_end_in_frames = output_block.end_frame_index();
|
||||||
}
|
}
|
||||||
|
|
||||||
output_thread_data->m_waiting_for_upstream_data = !can_carry_data(status);
|
output_thread_data->m_waiting_for_upstream_data = !can_carry_data(status);
|
||||||
|
|
@ -279,7 +279,7 @@ ReadonlySpan<float> AudioPlaybackSink::OutputThreadData::move_output_to_playback
|
||||||
while (samples_written < buffer.size() && m_block_count > 0) {
|
while (samples_written < buffer.size() && m_block_count > 0) {
|
||||||
auto const& head_block = m_blocks[m_block_head];
|
auto const& head_block = m_blocks[m_block_head];
|
||||||
auto channel_count = head_block.channel_count();
|
auto channel_count = head_block.channel_count();
|
||||||
auto block_start_frame = head_block.timestamp_in_frames();
|
auto block_start_frame = head_block.first_frame_index();
|
||||||
auto block_end_frame = block_start_frame + static_cast<i64>(head_block.frame_count());
|
auto block_end_frame = block_start_frame + static_cast<i64>(head_block.frame_count());
|
||||||
|
|
||||||
if (m_next_frame_to_play >= block_end_frame) {
|
if (m_next_frame_to_play >= block_end_frame) {
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,8 @@ static inline void decode_audio(StringView path, u32 sample_rate, u8 channel_cou
|
||||||
if (expected_channel_map.has_value())
|
if (expected_channel_map.has_value())
|
||||||
EXPECT_EQ(block.sample_specification().channel_map(), expected_channel_map.value());
|
EXPECT_EQ(block.sample_specification().channel_map(), expected_channel_map.value());
|
||||||
|
|
||||||
VERIFY(frame_count == 0 || last_frame <= block.timestamp_in_frames());
|
VERIFY(frame_count == 0 || last_frame <= block.first_frame_index());
|
||||||
last_frame = block.timestamp_in_frames() + static_cast<i64>(block.frame_count());
|
last_frame = block.first_frame_index() + static_cast<i64>(block.frame_count());
|
||||||
|
|
||||||
frame_count += block.frame_count();
|
frame_count += block.frame_count();
|
||||||
} else if (status == Media::PipelineStatus::EndOfStream) {
|
} else if (status == Media::PipelineStatus::EndOfStream) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue