| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/bind.h" | |
| 6 #include "base/bind_helpers.h" | |
| 7 #include "base/logging.h" | |
| 8 #include "base/message_loop/message_loop.h" | |
| 9 #include "services/media/framework_mojo/mojo_producer.h" | |
| 10 | |
| 11 namespace mojo { | |
| 12 namespace media { | |
| 13 | |
| 14 MojoProducer::MojoProducer() { | |
| 15 task_runner_ = base::MessageLoop::current()->task_runner(); | |
| 16 DCHECK(task_runner_); | |
| 17 } | |
| 18 | |
| 19 MojoProducer::~MojoProducer() { | |
| 20 base::AutoLock lock(lock_); | |
| 21 } | |
| 22 | |
| 23 void MojoProducer::AddBinding(InterfaceRequest<MediaProducer> producer) { | |
| 24 bindings_.AddBinding(this, producer.Pass()); | |
| 25 } | |
| 26 | |
| 27 void MojoProducer::PrimeConnection(const PrimeConnectionCallback& callback) { | |
| 28 Demand demand; | |
| 29 | |
| 30 if (consumer_.is_bound()) { | |
| 31 base::AutoLock lock(lock_); | |
| 32 max_pushes_outstanding_ = 4; // TODO(dalesat): Made up! | |
| 33 demand = current_pushes_outstanding_ < max_pushes_outstanding_ | |
| 34 ? Demand::kPositive | |
| 35 : Demand::kNegative; | |
| 36 } else { | |
| 37 demand = Demand::kNeutral; | |
| 38 if (!mojo_allocator_.initialized()) { | |
| 39 mojo_allocator_.InitNew(4096 * 1024); // TODO(dalesat): Made up! | |
| 40 } | |
| 41 } | |
| 42 | |
| 43 DCHECK(demand_callback_); | |
| 44 demand_callback_(demand); | |
| 45 | |
| 46 if (consumer_.is_bound()) { | |
| 47 consumer_->Prime([this, callback]() { callback.Run(); }); | |
| 48 } else { | |
| 49 callback.Run(); | |
| 50 } | |
| 51 } | |
| 52 | |
| 53 void MojoProducer::FlushConnection(const FlushConnectionCallback& callback) { | |
| 54 { | |
| 55 base::AutoLock lock(lock_); | |
| 56 max_pushes_outstanding_ = 0; | |
| 57 } | |
| 58 | |
| 59 DCHECK(demand_callback_); | |
| 60 demand_callback_(Demand::kNegative); | |
| 61 | |
| 62 if (consumer_.is_bound()) { | |
| 63 consumer_->Flush(callback); | |
| 64 } else { | |
| 65 callback.Run(); | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 PayloadAllocator* MojoProducer::allocator() { | |
| 70 return &mojo_allocator_; | |
| 71 } | |
| 72 | |
| 73 void MojoProducer::SetDemandCallback(const DemandCallback& demand_callback) { | |
| 74 demand_callback_ = demand_callback; | |
| 75 } | |
| 76 | |
| 77 Demand MojoProducer::SupplyPacket(PacketPtr packet) { | |
| 78 DCHECK(packet); | |
| 79 | |
| 80 // If we're not connected, throw the packet away. | |
| 81 if (!consumer_.is_bound()) { | |
| 82 return packet->end_of_stream() ? Demand::kNegative : Demand::kNeutral; | |
| 83 } | |
| 84 | |
| 85 Demand demand; | |
| 86 | |
| 87 { | |
| 88 base::AutoLock lock(lock_); | |
| 89 DCHECK(current_pushes_outstanding_ < max_pushes_outstanding_); | |
| 90 | |
| 91 ++current_pushes_outstanding_; | |
| 92 | |
| 93 if (packet->end_of_stream()) { | |
| 94 demand = Demand::kNegative; | |
| 95 max_pushes_outstanding_ = 0; | |
| 96 } else { | |
| 97 demand = current_pushes_outstanding_ < max_pushes_outstanding_ | |
| 98 ? Demand::kPositive | |
| 99 : Demand::kNegative; | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 MediaPacketPtr media_packet = CreateMediaPacket(packet); | |
| 104 task_runner_->PostTask( | |
| 105 FROM_HERE, | |
| 106 base::Bind(&MojoProducer::SendPacket, base::Unretained(this), | |
| 107 packet.release(), base::Passed(media_packet.Pass()))); | |
| 108 | |
| 109 return demand; | |
| 110 } | |
| 111 | |
| 112 void MojoProducer::Connect(InterfaceHandle<MediaConsumer> consumer, | |
| 113 const ConnectCallback& callback) { | |
| 114 DCHECK(consumer); | |
| 115 | |
| 116 consumer_ = MediaConsumerPtr::Create(std::move(consumer)); | |
| 117 | |
| 118 if (!mojo_allocator_.initialized()) { | |
| 119 mojo_allocator_.InitNew(4096 * 1024); // TODO(dalesat): Made up! | |
| 120 } | |
| 121 | |
| 122 consumer_->SetBuffer(mojo_allocator_.GetDuplicateHandle(), | |
| 123 [callback]() { callback.Run(); }); | |
| 124 } | |
| 125 | |
| 126 void MojoProducer::Disconnect() { | |
| 127 DCHECK(demand_callback_); | |
| 128 demand_callback_(Demand::kNegative); | |
| 129 consumer_.reset(); | |
| 130 } | |
| 131 | |
| 132 void MojoProducer::SendPacket(Packet* packet_raw_ptr, | |
| 133 MediaPacketPtr media_packet) { | |
| 134 consumer_->SendPacket( | |
| 135 media_packet.Pass(), | |
| 136 [this, packet_raw_ptr](MediaConsumer::SendResult send_result) { | |
| 137 PacketPtr packet = PacketPtr(packet_raw_ptr); | |
| 138 Demand demand; | |
| 139 | |
| 140 { | |
| 141 base::AutoLock lock(lock_); | |
| 142 demand = --current_pushes_outstanding_ < max_pushes_outstanding_ | |
| 143 ? Demand::kPositive | |
| 144 : Demand::kNegative; | |
| 145 } | |
| 146 | |
| 147 DCHECK(demand_callback_); | |
| 148 demand_callback_(demand); | |
| 149 }); | |
| 150 } | |
| 151 | |
| 152 MediaPacketPtr MojoProducer::CreateMediaPacket(const PacketPtr& packet) { | |
| 153 DCHECK(packet); | |
| 154 | |
| 155 MediaPacketRegionPtr region = MediaPacketRegion::New(); | |
| 156 region->offset = packet->size() == 0 | |
| 157 ? 0 | |
| 158 : mojo_allocator_.OffsetFromPtr(packet->payload()); | |
| 159 region->length = packet->size(); | |
| 160 | |
| 161 MediaPacketPtr media_packet = MediaPacket::New(); | |
| 162 media_packet->pts = packet->pts(); | |
| 163 media_packet->end_of_stream = packet->end_of_stream(); | |
| 164 media_packet->payload = region.Pass(); | |
| 165 | |
| 166 return media_packet.Pass(); | |
| 167 } | |
| 168 | |
| 169 } // namespace media | |
| 170 } // namespace mojo | |
| OLD | NEW |