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 "services/media/framework/graph.h" |
| 6 |
| 7 namespace mojo { |
| 8 namespace media { |
| 9 |
| 10 Graph::Graph() { |
| 11 update_function_ = [this](Stage* stage) { |
| 12 engine_.RequestUpdate(stage); |
| 13 }; |
| 14 } |
| 15 |
| 16 Graph::~Graph() { |
| 17 Reset(); |
| 18 } |
| 19 |
| 20 void Graph::RemovePart(PartRef part) { |
| 21 DCHECK(part.valid()); |
| 22 |
| 23 Stage* stage = part.stage_; |
| 24 |
| 25 size_t input_count = stage->input_count(); |
| 26 for (size_t input_index = 0; input_index < input_count; input_index++) { |
| 27 if (stage->input(input_index).connected()) { |
| 28 DisconnectInput(InputRef(stage, input_index)); |
| 29 } |
| 30 } |
| 31 |
| 32 size_t output_count = stage->output_count(); |
| 33 for (size_t output_index = 0; output_index < output_count; output_index++) { |
| 34 if (stage->output(output_index).connected()) { |
| 35 DisconnectOutput(OutputRef(stage, output_index)); |
| 36 } |
| 37 } |
| 38 |
| 39 stage->SetUpdateCallback(nullptr); |
| 40 |
| 41 sources_.remove(stage); |
| 42 sinks_.remove(stage); |
| 43 stages_.remove(stage); |
| 44 |
| 45 delete stage; |
| 46 } |
| 47 |
| 48 PartRef Graph::Connect(const OutputRef& output, const InputRef& input) { |
| 49 DCHECK(output.valid()); |
| 50 DCHECK(input.valid()); |
| 51 |
| 52 if (output.connected()) { |
| 53 DisconnectOutput(output); |
| 54 } |
| 55 if (input.connected()) { |
| 56 DisconnectInput(input); |
| 57 } |
| 58 |
| 59 output.actual().Connect(input); |
| 60 input.actual().Connect(output); |
| 61 |
| 62 return input.part(); |
| 63 } |
| 64 |
| 65 PartRef Graph::ConnectParts( |
| 66 PartRef upstream_part, |
| 67 PartRef downstream_part) { |
| 68 DCHECK(upstream_part.valid()); |
| 69 DCHECK(downstream_part.valid()); |
| 70 Connect(upstream_part.output(), downstream_part.input()); |
| 71 return downstream_part; |
| 72 } |
| 73 |
| 74 PartRef Graph::ConnectOutputToPart( |
| 75 const OutputRef& output, |
| 76 PartRef downstream_part) { |
| 77 DCHECK(output.valid()); |
| 78 DCHECK(downstream_part.valid()); |
| 79 Connect(output, downstream_part.input()); |
| 80 return downstream_part; |
| 81 } |
| 82 |
| 83 PartRef Graph::ConnectPartToInput( |
| 84 PartRef upstream_part, |
| 85 const InputRef& input) { |
| 86 DCHECK(upstream_part.valid()); |
| 87 DCHECK(input.valid()); |
| 88 Connect(upstream_part.output(), input); |
| 89 return input.part(); |
| 90 } |
| 91 |
| 92 void Graph::DisconnectOutput(const OutputRef& output) { |
| 93 DCHECK(output.valid()); |
| 94 |
| 95 if (!output.connected()) { |
| 96 return; |
| 97 } |
| 98 |
| 99 Input& mate = output.mate().actual(); |
| 100 |
| 101 if (mate.prepared()) { |
| 102 CHECK(false) << "attempt to disconnect prepared output"; |
| 103 return; |
| 104 } |
| 105 |
| 106 mate.Disconnect(); |
| 107 output.actual().Disconnect(); |
| 108 } |
| 109 |
| 110 void Graph::DisconnectInput(const InputRef& input) { |
| 111 DCHECK(input.valid()); |
| 112 |
| 113 if (!input.connected()) { |
| 114 return; |
| 115 } |
| 116 |
| 117 Output& mate = input.mate().actual(); |
| 118 |
| 119 if (input.actual().prepared()) { |
| 120 CHECK(false) << "attempt to disconnect prepared input"; |
| 121 return; |
| 122 } |
| 123 |
| 124 mate.Disconnect(); |
| 125 input.actual().Disconnect(); |
| 126 } |
| 127 |
| 128 void Graph::RemovePartsConnectedToPart(PartRef part) { |
| 129 DCHECK(part.valid()); |
| 130 |
| 131 std::deque<PartRef> to_remove { part }; |
| 132 |
| 133 while (!to_remove.empty()) { |
| 134 PartRef part = to_remove.front(); |
| 135 to_remove.pop_front(); |
| 136 |
| 137 for (size_t i = 0; i < part.input_count(); ++i) { |
| 138 to_remove.push_back(part.input(i).part()); |
| 139 } |
| 140 |
| 141 for (size_t i = 0; i < part.output_count(); ++i) { |
| 142 to_remove.push_back(part.output(i).part()); |
| 143 } |
| 144 |
| 145 RemovePart(part); |
| 146 } |
| 147 } |
| 148 |
| 149 void Graph::RemovePartsConnectedToOutput(const OutputRef& output) { |
| 150 DCHECK(output.valid()); |
| 151 |
| 152 if (!output.connected()) { |
| 153 return; |
| 154 } |
| 155 |
| 156 PartRef downstream_part = output.mate().part(); |
| 157 DisconnectOutput(output); |
| 158 RemovePartsConnectedToPart(downstream_part); |
| 159 } |
| 160 |
| 161 void Graph::RemovePartsConnectedToInput(const InputRef& input) { |
| 162 DCHECK(input.valid()); |
| 163 |
| 164 if (!input.connected()) { |
| 165 return; |
| 166 } |
| 167 |
| 168 PartRef upstream_part = input.mate().part(); |
| 169 DisconnectInput(input); |
| 170 RemovePartsConnectedToPart(upstream_part); |
| 171 } |
| 172 |
| 173 void Graph::Reset() { |
| 174 sources_.clear(); |
| 175 sinks_.clear(); |
| 176 while (!stages_.empty()) { |
| 177 Stage* stage = stages_.front(); |
| 178 stages_.pop_front(); |
| 179 delete stage; |
| 180 } |
| 181 } |
| 182 |
| 183 void Graph::Prepare() { |
| 184 for (Stage* sink : sinks_) { |
| 185 for (size_t i = 0; i < sink->input_count(); ++i) { |
| 186 engine_.PrepareInput(InputRef(sink, i)); |
| 187 } |
| 188 } |
| 189 } |
| 190 |
| 191 void Graph::PrepareInput(const InputRef& input) { |
| 192 DCHECK(input.valid()); |
| 193 engine_.PrepareInput(input); |
| 194 } |
| 195 |
| 196 void Graph::PrimeSinks() { |
| 197 for (Stage* sink : sinks_) { |
| 198 sink->Prime(); |
| 199 } |
| 200 } |
| 201 |
| 202 PartRef Graph::Add(Stage* stage) { |
| 203 stages_.push_back(stage); |
| 204 |
| 205 if (stage->input_count() == 0) { |
| 206 sources_.push_back(stage); |
| 207 } |
| 208 |
| 209 if (stage->output_count() == 0) { |
| 210 sinks_.push_back(stage); |
| 211 } |
| 212 |
| 213 stage->SetUpdateCallback(update_function_); |
| 214 |
| 215 return PartRef(stage); |
| 216 } |
| 217 |
| 218 } // namespace media |
| 219 } // namespace mojo |
OLD | NEW |