| Index: services/media/framework/stages/lpcm_stage_output.cc
|
| diff --git a/services/media/framework/stages/lpcm_stage_output.cc b/services/media/framework/stages/lpcm_stage_output.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4518148b516f624c247f0a98d83500ea40696048
|
| --- /dev/null
|
| +++ b/services/media/framework/stages/lpcm_stage_output.cc
|
| @@ -0,0 +1,114 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "services/media/framework/engine.h"
|
| +#include "services/media/framework/stages/lpcm_stage_input.h"
|
| +#include "services/media/framework/stages/lpcm_stage_output.h"
|
| +#include "services/media/framework/stages/stage.h"
|
| +
|
| +namespace mojo {
|
| +namespace media {
|
| +
|
| +LpcmStageOutput::LpcmStageOutput() :
|
| + next_presentation_time_(0),
|
| + buffer_(nullptr),
|
| + buffer_frame_count_(0) {}
|
| +
|
| +LpcmStageOutput::~LpcmStageOutput() {}
|
| +
|
| +LpcmDemand& LpcmStageOutput::lpcm_demand_from_downstream(
|
| + uint64_t suggested_frame_count) {
|
| +
|
| + if (mate().get_lpcm() == nullptr &&
|
| + demand_from_downstream() != Demand::kNegative &&
|
| + buffer_ == nullptr) {
|
| + // This output has to adapt to a non-lpcm input. There's currently no
|
| + // buffer, so we create one. In supply_frames, it will be made into a
|
| + // packet and sent downstream.
|
| + buffer_frame_count_ =
|
| + suggested_frame_count == 0 ? kDefaultFrameCount : suggested_frame_count;
|
| +
|
| + DCHECK(copy_allocator_);
|
| + DCHECK(lpcm_demand_from_downstream_.frames_.bytes_per_frame_);
|
| +
|
| + buffer_ = copy_allocator_->AllocatePayloadBuffer(buffer_frame_count_ *
|
| + lpcm_demand_from_downstream_.frames_.bytes_per_frame_);
|
| + lpcm_demand_from_downstream_.frames_.buffer_ = buffer_;
|
| + lpcm_demand_from_downstream_.frames_.frame_count_ = buffer_frame_count_;
|
| + lpcm_demand_from_downstream_.mix_ = false;
|
| + }
|
| +
|
| + return lpcm_demand_from_downstream_;
|
| +}
|
| +
|
| +void LpcmStageOutput::supply_frames(bool end_of_stream, Engine& engine) {
|
| + DCHECK(connected());
|
| + DCHECK(lpcm_demand_from_downstream_.frames_.buffer_ || end_of_stream);
|
| +
|
| + LpcmStageInput* lpcm_mate = mate().get_lpcm();
|
| + if (lpcm_mate != nullptr) {
|
| + // The downstream input is lpcm.
|
| + if (lpcm_demand_from_downstream_.frames_.frame_count_ != 0 &&
|
| + !lpcm_demand_from_downstream_.mix_) {
|
| + // We didn't finish filling the buffer, but we've hit end of stream. Zero
|
| + // the remaining frames.
|
| + lpcm_util_->Silence(
|
| + lpcm_demand_from_downstream_.frames_.buffer_,
|
| + lpcm_demand_from_downstream_.frames_.frame_count_);
|
| + NOTREACHED();
|
| + }
|
| +
|
| + lpcm_demand_from_downstream_.frames_.buffer_ = nullptr;
|
| + lpcm_demand_from_downstream_.frames_.frame_count_ = 0;
|
| +
|
| + if (lpcm_mate->supply_frames_internal(end_of_stream)) {
|
| + engine.PushToSupplyBacklog(downstream_stage());
|
| + }
|
| + return;
|
| + }
|
| +
|
| + // The downstream input isn't lpcm. We need to supply a packet.
|
| + uint64_t duration =
|
| + buffer_frame_count_ - lpcm_demand_from_downstream_.frames_.frame_count_;
|
| +
|
| + DCHECK(buffer_ || duration == 0);
|
| + DCHECK(buffer_frame_count_ || duration == 0);
|
| +
|
| + supply_packet_internal(
|
| + Packet::Create(
|
| + next_presentation_time_,
|
| + duration,
|
| + end_of_stream,
|
| + duration * lpcm_demand_from_downstream_.frames_.bytes_per_frame_,
|
| + duration == 0 ? nullptr : buffer_,
|
| + copy_allocator_),
|
| + engine);
|
| +
|
| + lpcm_demand_from_downstream_.frames_.buffer_ = nullptr;
|
| + lpcm_demand_from_downstream_.frames_.frame_count_ = 0;
|
| + next_presentation_time_ += buffer_frame_count_;
|
| + buffer_ = nullptr;
|
| + buffer_frame_count_ = 0;
|
| +}
|
| +
|
| +Allocator* LpcmStageOutput::Prepare(bool can_accept_allocator) {
|
| + // The stage isn't concerned with allocators, but we'll need one if our mate
|
| + // isn't lpcm.
|
| + Allocator* allocator = StageOutput::Prepare(true);
|
| + DCHECK(mate().get_lpcm() == nullptr || allocator == nullptr);
|
| + if (mate().get_lpcm() == nullptr) {
|
| + // Our mate isn't lpcm, so we'll need an allocator to create packet buffers.
|
| + // Use the provided one or the default.
|
| + copy_allocator_ =
|
| + allocator == nullptr ? Allocator::GetDefault() : allocator;
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| +LpcmStageOutput* LpcmStageOutput::get_lpcm() {
|
| + return this;
|
| +}
|
| +
|
| +} // namespace media
|
| +} // namespace mojo
|
|
|