Chromium Code Reviews| Index: services/media/framework/stages/stage_output.cc |
| diff --git a/services/media/framework/stages/stage_output.cc b/services/media/framework/stages/stage_output.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..27ef66005c7dd467a9db7f34020ed24d01a1d0ee |
| --- /dev/null |
| +++ b/services/media/framework/stages/stage_output.cc |
| @@ -0,0 +1,113 @@ |
| +// 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/stage.h" |
| +#include "services/media/framework/stages/stage_output.h" |
| + |
| +namespace mojo { |
| +namespace media { |
| + |
| +StageOutput::StageOutput() : |
| + copy_allocator_(nullptr), |
| + downstream_stage_(nullptr), |
| + input_index_(0), |
| + demand_(Demand::kNegative) {} |
| + |
| +StageOutput::~StageOutput() {} |
| + |
| +StageInput& StageOutput::mate() const { |
| + DCHECK(downstream_stage_); |
| + DCHECK(input_index_ < downstream_stage_->input_count()); |
| + return downstream_stage_->input(input_index_); |
| +} |
| + |
| +Allocator* StageOutput::Prepare(bool can_accept_allocator) { |
| + DCHECK(connected()); |
| + StageInput& mate = this->mate(); |
| + copy_allocator_ = nullptr; |
| + |
| + if (can_accept_allocator) { |
| + // We can use an allocator. Use our mate's allocator, if it has one. |
| + return mate.allocator(); |
| + } else if (mate.must_allocate()) { |
| + // We can't use an allocator, but our mate needs us to. We'll need to copy |
| + // every packet. |
| + copy_allocator_ = mate.allocator(); |
| + DCHECK(copy_allocator_); |
| + return nullptr; |
| + } else { |
| + // We can't use an allocator, and our mate doesn't need us to. |
| + return nullptr; |
| + } |
| +} |
| + |
| +Demand StageOutput::demand() const { |
| + DCHECK(connected()); |
| + |
| + // Return negative demand if mate() already has a packet. |
| + if (demand_ == Demand::kNegative || mate().packet_from_upstream()) { |
|
johngro
2016/01/26 23:47:30
this check (demand == negative) is redundant. It
dalesat
2016/01/28 18:49:16
I did this to avoid the second conditional when th
|
| + return Demand::kNegative; |
| + } |
| + |
| + return demand_; |
| +} |
| + |
| +void StageOutput::supply_packet(PacketPtr packet, Engine* engine) const { |
| + DCHECK(packet); |
| + DCHECK(engine); |
| + DCHECK(connected()); |
| + |
| + if (copy_allocator_ != nullptr) { |
| + // Need to copy the packet due to an allocation conflict. |
| + uint64_t size = packet->size(); |
| + void *buffer; |
| + |
| + if (size == 0) { |
| + buffer = nullptr; |
| + } else { |
| + buffer = copy_allocator_->AllocatePayloadBuffer(size); |
| + if (buffer == nullptr) { |
| + // Starved for buffer space. |
| + return; |
| + } |
| + memcpy(buffer, packet->payload(), size); |
| + } |
| + |
| + packet = Packet::Create( |
| + packet->presentation_time(), |
| + packet->duration(), |
| + packet->end_of_stream(), |
| + size, |
| + buffer, |
| + copy_allocator_); |
| + } |
| + |
| + supply_packet_internal(std::move(packet), engine); |
| +} |
| + |
| +bool StageOutput::update_demand_internal(Demand demand) { |
| + if (demand_ == demand) { |
| + return false; |
| + } |
| + demand_ = demand; |
| + return true; |
| +} |
| + |
| +LpcmStageOutput* StageOutput::get_lpcm() { |
| + return nullptr; |
| +} |
| + |
| +void StageOutput::supply_packet_internal(PacketPtr packet, Engine* engine) |
| + const { |
| + DCHECK(packet); |
| + DCHECK(engine); |
| + DCHECK(connected()); |
| + if (mate().supply_packet_internal(std::move(packet))) { |
| + engine->PushToSupplyBacklogUnsafe(downstream_stage()); |
| + } |
| +} |
| + |
| +} // namespace media |
| +} // namespace mojo |