Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(940)

Side by Side Diff: chrome/browser/media/cast_remoting_sender.cc

Issue 2310753002: Media Remoting: Data/Control plumbing between renderer and Media Router. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 "chrome/browser/media/cast_remoting_sender.h"
6
7 #include <map>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/lazy_instance.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "media/base/bind_to_current_loop.h"
15
16 using content::BrowserThread;
17
18 namespace {
19
20 // Global map for looking-up CastRemotingSender instances by their
21 // |rtp_stream_id|.
22 using CastRemotingSenderMap = std::map<int32_t, CastRemotingSender*>;
23 base::LazyInstance<CastRemotingSenderMap>::Leaky g_sender_map =
24 LAZY_INSTANCE_INITIALIZER;
25
26 } // namespace
27
28 CastRemotingSender::CastRemotingSender(int32_t rtp_stream_id)
29 : rtp_stream_id_(rtp_stream_id), binding_(this) {
30 DCHECK_CURRENTLY_ON(BrowserThread::IO);
31 CastRemotingSender*& pointer_in_map = g_sender_map.Get()[rtp_stream_id_];
32 DCHECK(!pointer_in_map);
33 pointer_in_map = this;
34 }
35
36 CastRemotingSender::~CastRemotingSender() {
37 DCHECK_CURRENTLY_ON(BrowserThread::IO);
38 g_sender_map.Pointer()->erase(rtp_stream_id_);
39 }
40
41 // static
42 void CastRemotingSender::FindAndBind(
43 int32_t rtp_stream_id,
44 mojo::ScopedDataPipeConsumerHandle pipe,
45 media::mojom::RemotingDataStreamSenderRequest request,
46 const base::Closure& error_callback) {
47 // CastRemotingSender lives entirely on the IO thread, so trampoline if
48 // necessary.
49 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
50 BrowserThread::PostTask(
51 BrowserThread::IO, FROM_HERE,
52 base::Bind(&CastRemotingSender::FindAndBind, rtp_stream_id,
53 base::Passed(&pipe), base::Passed(&request),
54 // Using media::BindToCurrentLoop() so the |error_callback|
55 // is trampolined back to the original thread.
56 media::BindToCurrentLoop(error_callback)));
57 return;
58 }
59
60 DCHECK(!error_callback.is_null());
61
62 // Look-up the CastRemotingSender instance by its |rtp_stream_id|.
63 const auto it = g_sender_map.Pointer()->find(rtp_stream_id);
64 if (it == g_sender_map.Pointer()->end()) {
65 DLOG(ERROR) << "Cannot find CastRemotingSender instance by ID: "
66 << rtp_stream_id;
67 error_callback.Run();
68 return;
69 }
70
71 // Confirm that the CastRemotingSender isn't already bound to a message pipe.
72 CastRemotingSender* const sender = it->second;
73 if (sender->binding_.is_bound()) {
74 DLOG(ERROR) << "Attempt to bind to CastRemotingSender a second time (id="
75 << rtp_stream_id << ")!";
76 error_callback.Run();
77 return;
78 }
79
80 DCHECK(sender->error_callback_.is_null());
81 sender->error_callback_ = error_callback;
82
83 sender->pipe_ = std::move(pipe);
84 sender->binding_.Bind(std::move(request));
85 sender->binding_.set_connection_error_handler(
86 base::Bind(&base::Closure::Run,
87 base::Unretained(&sender->error_callback_)));
88 }
89
90 void CastRemotingSender::ConsumeDataChunk(uint32_t offset, uint32_t size,
91 uint32_t total_payload_size) {
92 DCHECK_CURRENTLY_ON(BrowserThread::IO);
93
94 const void* buffer;
95 uint32_t buffer_num_bytes = size;
96 if (offset + size > total_payload_size || !pipe_.is_valid() ||
97 mojo::BeginReadDataRaw(pipe_.get(), &buffer, &buffer_num_bytes,
98 MOJO_READ_DATA_FLAG_ALL_OR_NONE) !=
99 MOJO_RESULT_OK ||
100 buffer_num_bytes != size) {
101 pipe_.reset();
102 binding_.Close();
103 error_callback_.Run();
104 return;
105 }
106 // If |total_payload_size| has changed, resize the data string. If it has not
107 // changed, the following statement will be a no-op.
108 next_frame_data_.resize(total_payload_size, '\0');
109 memcpy(&next_frame_data_.front() + offset, buffer, buffer_num_bytes);
110 mojo::EndReadDataRaw(pipe_.get(), buffer_num_bytes);
111 }
112
113 void CastRemotingSender::SendFrame() {
114 DCHECK_CURRENTLY_ON(BrowserThread::IO);
115
116 // TODO(miu): Merge with xjz's recent change, which implements this
117 // functionality.
118 NOTIMPLEMENTED(); // encoder_frame.data.swap(next_frame_data_)
119 }
120
121 void CastRemotingSender::CancelInFlightData() {
122 DCHECK_CURRENTLY_ON(BrowserThread::IO);
123
124 // Note: Not calling clear(), in order to force a significant amount of memory
125 // to be freed.
126 std::string().swap(next_frame_data_);
127
128 // TODO(miu): Merge with xjz's recent change, which implements this
129 // functionality.
130 NOTIMPLEMENTED(); // transport_->CancelSendingFrames(...);
131 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698