| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/public/cpp/environment/logging.h" | 5 #include "mojo/public/cpp/environment/logging.h" |
| 6 #include "mojo/public/cpp/utility/run_loop.h" | 6 #include "mojo/public/cpp/utility/run_loop.h" |
| 7 #include "mojo/services/media/common/cpp/circular_buffer_media_pipe_adapter.h" | 7 #include "mojo/services/media/common/cpp/circular_buffer_media_pipe_adapter.h" |
| 8 #include "mojo/services/media/common/interfaces/media_common.mojom.h" | 8 #include "mojo/services/media/common/interfaces/media_common.mojom.h" |
| 9 #include "mojo/services/media/common/interfaces/media_pipe.mojom.h" | 9 #include "mojo/services/media/common/interfaces/media_pipe.mojom.h" |
| 10 | 10 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 cbk_(cbk) {} | 32 cbk_(cbk) {} |
| 33 CircularBufferMediaPipeAdapter::PacketState::~PacketState() { } | 33 CircularBufferMediaPipeAdapter::PacketState::~PacketState() { } |
| 34 | 34 |
| 35 CircularBufferMediaPipeAdapter::CircularBufferMediaPipeAdapter( | 35 CircularBufferMediaPipeAdapter::CircularBufferMediaPipeAdapter( |
| 36 MediaPipePtr pipe) | 36 MediaPipePtr pipe) |
| 37 : pipe_(pipe.Pass()) | 37 : pipe_(pipe.Pass()) |
| 38 , thiz_(new CircularBufferMediaPipeAdapter*(this)) { | 38 , thiz_(new CircularBufferMediaPipeAdapter*(this)) { |
| 39 MOJO_DCHECK(pipe_); | 39 MOJO_DCHECK(pipe_); |
| 40 MOJO_DCHECK(RunLoop::current()); | 40 MOJO_DCHECK(RunLoop::current()); |
| 41 | 41 |
| 42 pipe_get_state_cbk_ = MediaPipe::GetStateCallback( | |
| 43 [this] (MediaPipeStatePtr state) { | |
| 44 HandleGetState(state.Pass()); | |
| 45 }); | |
| 46 | |
| 47 pipe_flush_cbk_ = MediaPipe::FlushCallback( | 42 pipe_flush_cbk_ = MediaPipe::FlushCallback( |
| 48 [this] () { | 43 [this] () { |
| 49 HandleFlush(); | 44 HandleFlush(); |
| 50 }); | 45 }); |
| 51 | 46 |
| 52 pipe_.set_connection_error_handler( | 47 pipe_.set_connection_error_handler( |
| 53 [this]() { | 48 [this]() { |
| 54 Fault(MediaResult::CONNECTION_LOST); | 49 Fault(MediaResult::CONNECTION_LOST); |
| 55 }); | 50 }); |
| 56 | 51 |
| 57 std::shared_ptr<CircularBufferMediaPipeAdapter*> thiz(thiz_); | 52 std::shared_ptr<CircularBufferMediaPipeAdapter*> thiz(thiz_); |
| 58 signalled_callback_ = Closure( | 53 signalled_callback_ = Closure( |
| 59 [thiz] () { | 54 [thiz] () { |
| 60 if (*thiz) { | 55 if (*thiz) { |
| 61 (*thiz)->HandleSignalCallback(); | 56 (*thiz)->HandleSignalCallback(); |
| 62 } | 57 } |
| 63 }); | 58 }); |
| 64 | |
| 65 | |
| 66 // Begin by getting a hold of the shared buffer from our pipe over which we | |
| 67 // will push data. | |
| 68 MOJO_DCHECK(get_state_in_progress_); | |
| 69 pipe_->GetState(pipe_get_state_cbk_); | |
| 70 } | 59 } |
| 71 | 60 |
| 72 CircularBufferMediaPipeAdapter::~CircularBufferMediaPipeAdapter() { | 61 CircularBufferMediaPipeAdapter::~CircularBufferMediaPipeAdapter() { |
| 73 *thiz_ = nullptr; | 62 *thiz_ = nullptr; |
| 74 Cleanup(); | 63 Cleanup(); |
| 75 } | 64 } |
| 76 | 65 |
| 66 void CircularBufferMediaPipeAdapter::Init(uint64_t size) { |
| 67 // Double Init? Fault unless the user is asking us to set up a buffer of the |
| 68 // same size. |
| 69 if (buffer_handle_.is_valid()) { |
| 70 if (buffer_size_ != size) { |
| 71 Fault(MediaResult::BAD_STATE); |
| 72 } |
| 73 return; |
| 74 } |
| 75 |
| 76 // Make the buffer |
| 77 MojoResult res = CreateSharedBuffer(nullptr, size, &buffer_handle_); |
| 78 if (res != MOJO_RESULT_OK) { |
| 79 MOJO_LOG(ERROR) << "Failed to allocate buffer of size " << size |
| 80 << " in " << __PRETTY_FUNCTION__ |
| 81 << " (error " << res << ")"; |
| 82 Fault(MediaResult::INSUFFICIENT_RESOURCES); |
| 83 return; |
| 84 } |
| 85 |
| 86 buffer_size_ = size; |
| 87 |
| 88 // Map the buffer |
| 89 // |
| 90 // TODO(johngro) : We really only need write access to this buffer. |
| 91 // Ideally, we could request that using flags, but there does not seem to be |
| 92 // a way to do this right now. |
| 93 res = MapBuffer(buffer_handle_.get(), |
| 94 0, |
| 95 buffer_size_, |
| 96 &buffer_, |
| 97 MOJO_MAP_BUFFER_FLAG_NONE); |
| 98 if (res != MOJO_RESULT_OK) { |
| 99 MOJO_LOG(ERROR) << "Failed to map buffer in " << __PRETTY_FUNCTION__ |
| 100 << " (error " << res << ")"; |
| 101 Fault(MediaResult::UNKNOWN_ERROR); |
| 102 return; |
| 103 } |
| 104 |
| 105 // Duplicate the buffer and send it to the other side of the pipe. |
| 106 // |
| 107 // TODO(johngro) : It would be nice if we could restrict this handle to be |
| 108 // read-only. |
| 109 ScopedSharedBufferHandle duplicated_handle; |
| 110 res = DuplicateBuffer(buffer_handle_.get(), nullptr, &duplicated_handle); |
| 111 if (res != MOJO_RESULT_OK) { |
| 112 MOJO_LOG(ERROR) << "Failed to duplicate handle in " << __PRETTY_FUNCTION__ |
| 113 << " (error " << res << ")"; |
| 114 Fault(MediaResult::UNKNOWN_ERROR); |
| 115 return; |
| 116 } |
| 117 |
| 118 // TODO(johngro) : We should not have to send the buffer size, it should be an |
| 119 // intrinsic property of the buffer itself and be query-able via the handle. |
| 120 pipe_->SetBuffer(duplicated_handle.Pass(), buffer_size_); |
| 121 } |
| 122 |
| 77 void CircularBufferMediaPipeAdapter::SetSignalCallback(SignalCbk cbk) { | 123 void CircularBufferMediaPipeAdapter::SetSignalCallback(SignalCbk cbk) { |
| 78 bool schedule; | 124 bool schedule; |
| 79 signal_cbk_ = cbk; | 125 signal_cbk_ = cbk; |
| 80 schedule = (signal_cbk_ != nullptr); | 126 schedule = (signal_cbk_ != nullptr); |
| 81 | 127 |
| 82 // If the user supplied a non-null callback, make sure we schedule a | 128 // If the user supplied a non-null callback, make sure we schedule a |
| 83 // callback if we are currently signalled. | 129 // callback if we are currently signalled. |
| 84 if (schedule) { | 130 if (schedule) { |
| 85 UpdateSignalled(); | 131 UpdateSignalled(); |
| 86 } | 132 } |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 in_flight_queue_.clear(); | 337 in_flight_queue_.clear(); |
| 292 rd_ = wr_ = 0; | 338 rd_ = wr_ = 0; |
| 293 flush_in_progress_ = true; | 339 flush_in_progress_ = true; |
| 294 flush_generation_++; | 340 flush_generation_++; |
| 295 | 341 |
| 296 pipe_->Flush(pipe_flush_cbk_); | 342 pipe_->Flush(pipe_flush_cbk_); |
| 297 | 343 |
| 298 return MediaResult::OK; | 344 return MediaResult::OK; |
| 299 } | 345 } |
| 300 | 346 |
| 301 void CircularBufferMediaPipeAdapter::HandleGetState(MediaPipeStatePtr state) { | |
| 302 MOJO_DCHECK(state); // We must have a state structure. | |
| 303 MOJO_DCHECK(!buffer_); // We must not have already mapped a buffer. | |
| 304 MOJO_DCHECK(get_state_in_progress_); // We should be waiting for our cbk. | |
| 305 | |
| 306 // Success or failure, we are no longer waiting for our get state callback. | |
| 307 get_state_in_progress_ = false; | |
| 308 rd_ = wr_ = 0; | |
| 309 | |
| 310 // Double init? How did that happen? | |
| 311 if (buffer_handle_.is_valid() || (nullptr != buffer_)) { | |
| 312 MOJO_LOG(ERROR) << "Double init during " << __PRETTY_FUNCTION__; | |
| 313 Fault(MediaResult::UNKNOWN_ERROR); | |
| 314 return; | |
| 315 } | |
| 316 | |
| 317 // No shared buffer? That's a fatal error. | |
| 318 if (!state->payload_buffer.is_valid()) { | |
| 319 MOJO_LOG(ERROR) << "Null payload buffer in " << __PRETTY_FUNCTION__; | |
| 320 Fault(MediaResult::UNKNOWN_ERROR); | |
| 321 return; | |
| 322 } | |
| 323 | |
| 324 // stash our state | |
| 325 buffer_handle_ = state->payload_buffer.Pass(); | |
| 326 buffer_size_ = state->payload_buffer_len; | |
| 327 | |
| 328 // Sanity checks the buffer size. | |
| 329 if (!buffer_size_ || (buffer_size_ > MediaPipeState::kMaxPayloadLen)) { | |
| 330 MOJO_LOG(ERROR) << "Bad buffer size in " << __PRETTY_FUNCTION__ | |
| 331 << " (" << buffer_size_ << ")"; | |
| 332 Fault(MediaResult::BAD_STATE); | |
| 333 return; | |
| 334 } | |
| 335 | |
| 336 // Map our buffer | |
| 337 // | |
| 338 // TODO(johngro) : We really only need write access to this buffer. | |
| 339 // Ideally, we could request that using flags, but there does not seem to be | |
| 340 // a way to do this right now. | |
| 341 MojoResult res; | |
| 342 res = MapBuffer(buffer_handle_.get(), | |
| 343 0, | |
| 344 buffer_size_, | |
| 345 &buffer_, | |
| 346 MOJO_MAP_BUFFER_FLAG_NONE); | |
| 347 if (res != MOJO_RESULT_OK) { | |
| 348 MOJO_LOG(ERROR) << "Failed to map buffer in " << __PRETTY_FUNCTION__ | |
| 349 << " (error " << res << ")"; | |
| 350 Fault(MediaResult::UNKNOWN_ERROR); | |
| 351 return; | |
| 352 } | |
| 353 | |
| 354 // Init is complete, we may be signalled now. | |
| 355 UpdateSignalled(); | |
| 356 } | |
| 357 | |
| 358 void CircularBufferMediaPipeAdapter::HandleSendPacket( | 347 void CircularBufferMediaPipeAdapter::HandleSendPacket( |
| 359 uint32_t seq_num, | 348 uint32_t seq_num, |
| 360 MediaPipe::SendResult result) { | 349 MediaPipe::SendResult result) { |
| 361 MediaPipe::SendPacketCallback cbk; | 350 MediaPipe::SendPacketCallback cbk; |
| 362 | 351 |
| 363 do { | 352 do { |
| 364 if (get_state_in_progress_) { | |
| 365 // If we are in the process of getting the initial state of the system, | |
| 366 // then something is seriously wrong. The other end of this interface is | |
| 367 // sending us Send callbacks while we are in the process of initializing | |
| 368 // (something which should be impossible) | |
| 369 Fault(MediaResult::PROTOCOL_ERROR); | |
| 370 break; | |
| 371 } | |
| 372 | |
| 373 // There should be at least one element in the in-flight queue, and the | 353 // There should be at least one element in the in-flight queue, and the |
| 374 // front of the queue's sequence number should match the sequence number of | 354 // front of the queue's sequence number should match the sequence number of |
| 375 // the payload being returned to us. | 355 // the payload being returned to us. |
| 376 if (!in_flight_queue_.size() || | 356 if (!in_flight_queue_.size() || |
| 377 (in_flight_queue_.front().seq_num_ != seq_num)) { | 357 (in_flight_queue_.front().seq_num_ != seq_num)) { |
| 378 Fault(MediaResult::UNKNOWN_ERROR); | 358 Fault(MediaResult::UNKNOWN_ERROR); |
| 379 break; | 359 break; |
| 380 } | 360 } |
| 381 | 361 |
| 382 uint64_t new_rd = in_flight_queue_.front().post_consume_rd_; | 362 uint64_t new_rd = in_flight_queue_.front().post_consume_rd_; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 uint64_t CircularBufferMediaPipeAdapter::GetBufferSize() const { | 517 uint64_t CircularBufferMediaPipeAdapter::GetBufferSize() const { |
| 538 if (nullptr == buffer_) | 518 if (nullptr == buffer_) |
| 539 return 0; | 519 return 0; |
| 540 | 520 |
| 541 MOJO_DCHECK(buffer_size_); | 521 MOJO_DCHECK(buffer_size_); |
| 542 return buffer_size_ - 1; | 522 return buffer_size_ - 1; |
| 543 } | 523 } |
| 544 | 524 |
| 545 } // namespace media | 525 } // namespace media |
| 546 } // namespace mojo | 526 } // namespace mojo |
| OLD | NEW |