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

Side by Side Diff: chrome/renderer/media/cast_session_delegate.cc

Issue 236123003: Cast: Provide more meaningful stats. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix compile Created 6 years, 8 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
« no previous file with comments | « chrome/renderer/media/cast_session_delegate.h ('k') | media/cast/cast.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chrome/renderer/media/cast_session_delegate.h" 5 #include "chrome/renderer/media/cast_session_delegate.h"
6 6
7 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop_proxy.h" 9 #include "base/message_loop/message_loop_proxy.h"
10 #include "chrome/renderer/media/cast_threads.h" 10 #include "chrome/renderer/media/cast_threads.h"
11 #include "chrome/renderer/media/cast_transport_sender_ipc.h" 11 #include "chrome/renderer/media/cast_transport_sender_ipc.h"
12 #include "content/public/renderer/render_thread.h" 12 #include "content/public/renderer/render_thread.h"
13 #include "media/cast/cast_config.h" 13 #include "media/cast/cast_config.h"
14 #include "media/cast/cast_environment.h" 14 #include "media/cast/cast_environment.h"
15 #include "media/cast/cast_sender.h" 15 #include "media/cast/cast_sender.h"
16 #include "media/cast/logging/encoding_event_subscriber.h"
17 #include "media/cast/logging/log_serializer.h" 16 #include "media/cast/logging/log_serializer.h"
18 #include "media/cast/logging/logging_defines.h" 17 #include "media/cast/logging/logging_defines.h"
19 #include "media/cast/logging/stats_event_subscriber.h" 18 #include "media/cast/logging/raw_event_subscriber_bundle.h"
20 #include "media/cast/logging/stats_util.h"
21 #include "media/cast/transport/cast_transport_config.h" 19 #include "media/cast/transport/cast_transport_config.h"
22 #include "media/cast/transport/cast_transport_sender.h" 20 #include "media/cast/transport/cast_transport_sender.h"
23 21
24 using media::cast::AudioSenderConfig; 22 using media::cast::AudioSenderConfig;
25 using media::cast::CastEnvironment; 23 using media::cast::CastEnvironment;
26 using media::cast::CastSender; 24 using media::cast::CastSender;
27 using media::cast::VideoSenderConfig; 25 using media::cast::VideoSenderConfig;
28 26
29 static base::LazyInstance<CastThreads> g_cast_threads = 27 static base::LazyInstance<CastThreads> g_cast_threads =
30 LAZY_INSTANCE_INITIALIZER; 28 LAZY_INSTANCE_INITIALIZER;
31 29
32 namespace {
33
34 // Allow 9MB for serialized video / audio event logs.
35 const int kMaxSerializedBytes = 9000000;
36
37 // Assume serialized log data for each frame will take up to 150 bytes.
38 const int kMaxVideoEventEntries = kMaxSerializedBytes / 150;
39
40 // Assume serialized log data for each frame will take up to 75 bytes.
41 const int kMaxAudioEventEntries = kMaxSerializedBytes / 75;
42
43 } // namespace
44
45 CastSessionDelegate::CastSessionDelegate() 30 CastSessionDelegate::CastSessionDelegate()
46 : io_message_loop_proxy_( 31 : io_message_loop_proxy_(
47 content::RenderThread::Get()->GetIOMessageLoopProxy()), 32 content::RenderThread::Get()->GetIOMessageLoopProxy()),
48 weak_factory_(this) { 33 weak_factory_(this) {
49 DCHECK(io_message_loop_proxy_); 34 DCHECK(io_message_loop_proxy_);
50 } 35 }
51 36
52 CastSessionDelegate::~CastSessionDelegate() { 37 CastSessionDelegate::~CastSessionDelegate() {
53 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 38 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
54
55 if (cast_environment_.get()) {
56 if (audio_event_subscriber_.get()) {
57 cast_environment_->Logging()->RemoveRawEventSubscriber(
58 audio_event_subscriber_.get());
59 }
60 if (video_event_subscriber_.get()) {
61 cast_environment_->Logging()->RemoveRawEventSubscriber(
62 video_event_subscriber_.get());
63 }
64 }
65 } 39 }
66 40
67 void CastSessionDelegate::StartAudio( 41 void CastSessionDelegate::StartAudio(
68 const AudioSenderConfig& config, 42 const AudioSenderConfig& config,
69 const AudioFrameInputAvailableCallback& callback, 43 const AudioFrameInputAvailableCallback& callback,
70 const ErrorCallback& error_callback) { 44 const ErrorCallback& error_callback) {
71 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 45 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
72 46
73 if (!cast_transport_ || !cast_sender_) { 47 if (!cast_transport_ || !cast_sender_) {
74 error_callback.Run("Destination not set."); 48 error_callback.Run("Destination not set.");
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 96 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
123 97
124 // CastSender uses the renderer's IO thread as the main thread. This reduces 98 // CastSender uses the renderer's IO thread as the main thread. This reduces
125 // thread hopping for incoming video frames and outgoing network packets. 99 // thread hopping for incoming video frames and outgoing network packets.
126 cast_environment_ = new CastEnvironment( 100 cast_environment_ = new CastEnvironment(
127 scoped_ptr<base::TickClock>(new base::DefaultTickClock()).Pass(), 101 scoped_ptr<base::TickClock>(new base::DefaultTickClock()).Pass(),
128 base::MessageLoopProxy::current(), 102 base::MessageLoopProxy::current(),
129 g_cast_threads.Get().GetAudioEncodeMessageLoopProxy(), 103 g_cast_threads.Get().GetAudioEncodeMessageLoopProxy(),
130 g_cast_threads.Get().GetVideoEncodeMessageLoopProxy()); 104 g_cast_threads.Get().GetVideoEncodeMessageLoopProxy());
131 105
106 event_subscribers_.reset(
107 new media::cast::RawEventSubscriberBundle(cast_environment_));
108
132 // Rationale for using unretained: The callback cannot be called after the 109 // Rationale for using unretained: The callback cannot be called after the
133 // destruction of CastTransportSenderIPC, and they both share the same thread. 110 // destruction of CastTransportSenderIPC, and they both share the same thread.
134 cast_transport_.reset(new CastTransportSenderIPC( 111 cast_transport_.reset(new CastTransportSenderIPC(
135 remote_endpoint, 112 remote_endpoint,
136 base::Bind(&CastSessionDelegate::StatusNotificationCB, 113 base::Bind(&CastSessionDelegate::StatusNotificationCB,
137 base::Unretained(this)), 114 base::Unretained(this)),
138 base::Bind(&CastSessionDelegate::LogRawEvents, base::Unretained(this)))); 115 base::Bind(&CastSessionDelegate::LogRawEvents, base::Unretained(this))));
139 116
140 cast_sender_ = CastSender::Create(cast_environment_, cast_transport_.get()); 117 cast_sender_ = CastSender::Create(cast_environment_, cast_transport_.get());
141 cast_transport_->SetPacketReceiver(cast_sender_->packet_receiver()); 118 cast_transport_->SetPacketReceiver(cast_sender_->packet_receiver());
142 } 119 }
143 120
144 void CastSessionDelegate::ToggleLogging(bool is_audio, bool enable) { 121 void CastSessionDelegate::ToggleLogging(bool is_audio, bool enable) {
145 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 122 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
146 if (!cast_environment_.get()) 123 if (!event_subscribers_.get())
147 return; 124 return;
148 if (enable) { 125
149 if (is_audio) { 126 if (enable)
150 if (!audio_event_subscriber_.get()) { 127 event_subscribers_->AddEventSubscribers(is_audio);
151 audio_event_subscriber_.reset(new media::cast::EncodingEventSubscriber( 128 else
152 media::cast::AUDIO_EVENT, kMaxAudioEventEntries)); 129 event_subscribers_->RemoveEventSubscribers(is_audio);
153 cast_environment_->Logging()->AddRawEventSubscriber(
154 audio_event_subscriber_.get());
155 }
156 if (!audio_stats_subscriber_.get()) {
157 audio_stats_subscriber_.reset(
158 new media::cast::StatsEventSubscriber(media::cast::AUDIO_EVENT));
159 cast_environment_->Logging()->AddRawEventSubscriber(
160 audio_stats_subscriber_.get());
161 }
162 } else {
163 if (!video_event_subscriber_.get()) {
164 video_event_subscriber_.reset(new media::cast::EncodingEventSubscriber(
165 media::cast::VIDEO_EVENT, kMaxVideoEventEntries));
166 cast_environment_->Logging()->AddRawEventSubscriber(
167 video_event_subscriber_.get());
168 }
169 if (!video_stats_subscriber_.get()) {
170 video_stats_subscriber_.reset(
171 new media::cast::StatsEventSubscriber(media::cast::VIDEO_EVENT));
172 cast_environment_->Logging()->AddRawEventSubscriber(
173 video_stats_subscriber_.get());
174 }
175 }
176 } else {
177 if (is_audio) {
178 if (audio_event_subscriber_.get()) {
179 cast_environment_->Logging()->RemoveRawEventSubscriber(
180 audio_event_subscriber_.get());
181 audio_event_subscriber_.reset();
182 }
183 if (audio_stats_subscriber_.get()) {
184 cast_environment_->Logging()->RemoveRawEventSubscriber(
185 audio_stats_subscriber_.get());
186 audio_stats_subscriber_.reset();
187 }
188 } else {
189 if (video_event_subscriber_.get()) {
190 cast_environment_->Logging()->RemoveRawEventSubscriber(
191 video_event_subscriber_.get());
192 video_event_subscriber_.reset();
193 }
194 if (video_stats_subscriber_.get()) {
195 cast_environment_->Logging()->RemoveRawEventSubscriber(
196 video_stats_subscriber_.get());
197 video_stats_subscriber_.reset();
198 }
199 }
200 }
201 } 130 }
202 131
203 void CastSessionDelegate::GetEventLogsAndReset( 132 void CastSessionDelegate::GetEventLogsAndReset(
204 bool is_audio, 133 bool is_audio,
205 const EventLogsCallback& callback) { 134 const EventLogsCallback& callback) {
206 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 135 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
207 136
137 if (!event_subscribers_.get()) {
138 callback.Run(make_scoped_ptr(new base::BinaryValue).Pass());
139 return;
140 }
141
208 media::cast::EncodingEventSubscriber* subscriber = 142 media::cast::EncodingEventSubscriber* subscriber =
209 is_audio ? audio_event_subscriber_.get() : video_event_subscriber_.get(); 143 event_subscribers_->GetEncodingEventSubscriber(is_audio);
210 if (!subscriber) { 144 if (!subscriber) {
211 callback.Run(make_scoped_ptr(new base::BinaryValue).Pass()); 145 callback.Run(make_scoped_ptr(new base::BinaryValue).Pass());
212 return; 146 return;
213 } 147 }
214 148
215 media::cast::proto::LogMetadata metadata; 149 media::cast::proto::LogMetadata metadata;
216 media::cast::FrameEventList frame_events; 150 media::cast::FrameEventList frame_events;
217 media::cast::PacketEventList packet_events; 151 media::cast::PacketEventList packet_events;
218 152
219 subscriber->GetEventsAndReset(&metadata, &frame_events, &packet_events); 153 subscriber->GetEventsAndReset(&metadata, &frame_events, &packet_events);
220 154
221 scoped_ptr<char[]> serialized_log(new char[kMaxSerializedBytes]); 155 scoped_ptr<char[]> serialized_log(new char[media::cast::kMaxSerializedBytes]);
222 int output_bytes; 156 int output_bytes;
223 bool success = media::cast::SerializeEvents(metadata, 157 bool success = media::cast::SerializeEvents(metadata,
224 frame_events, 158 frame_events,
225 packet_events, 159 packet_events,
226 true, 160 true,
227 kMaxSerializedBytes, 161 media::cast::kMaxSerializedBytes,
228 serialized_log.get(), 162 serialized_log.get(),
229 &output_bytes); 163 &output_bytes);
230 164
231 if (!success) { 165 if (!success) {
232 VLOG(2) << "Failed to serialize event log."; 166 VLOG(2) << "Failed to serialize event log.";
233 callback.Run(make_scoped_ptr(new base::BinaryValue).Pass()); 167 callback.Run(make_scoped_ptr(new base::BinaryValue).Pass());
234 return; 168 return;
235 } 169 }
236 170
237 DVLOG(2) << "Serialized log length: " << output_bytes; 171 DVLOG(2) << "Serialized log length: " << output_bytes;
238 172
239 scoped_ptr<base::BinaryValue> blob( 173 scoped_ptr<base::BinaryValue> blob(
240 new base::BinaryValue(serialized_log.Pass(), output_bytes)); 174 new base::BinaryValue(serialized_log.Pass(), output_bytes));
241 callback.Run(blob.Pass()); 175 callback.Run(blob.Pass());
242 } 176 }
243 177
244 void CastSessionDelegate::GetStatsAndReset(bool is_audio, 178 void CastSessionDelegate::GetStatsAndReset(bool is_audio,
245 const StatsCallback& callback) { 179 const StatsCallback& callback) {
180 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
181
182 if (!event_subscribers_.get()) {
183 callback.Run(make_scoped_ptr(new base::DictionaryValue).Pass());
184 return;
185 }
186
246 media::cast::StatsEventSubscriber* subscriber = 187 media::cast::StatsEventSubscriber* subscriber =
247 is_audio ? audio_stats_subscriber_.get() : video_stats_subscriber_.get(); 188 event_subscribers_->GetStatsEventSubscriber(is_audio);
248 if (!subscriber) { 189 if (!subscriber) {
249 callback.Run(make_scoped_ptr(new base::DictionaryValue).Pass()); 190 callback.Run(make_scoped_ptr(new base::DictionaryValue).Pass());
250 return; 191 return;
251 } 192 }
252 193
253 media::cast::FrameStatsMap frame_stats; 194 scoped_ptr<base::DictionaryValue> stats = subscriber->GetStats();
254 subscriber->GetFrameStats(&frame_stats);
255 media::cast::PacketStatsMap packet_stats;
256 subscriber->GetPacketStats(&packet_stats);
257 subscriber->Reset(); 195 subscriber->Reset();
258 196
259 scoped_ptr<base::DictionaryValue> stats = media::cast::ConvertStats(
260 frame_stats, packet_stats);
261
262 callback.Run(stats.Pass()); 197 callback.Run(stats.Pass());
263 } 198 }
264 199
265 void CastSessionDelegate::StatusNotificationCB( 200 void CastSessionDelegate::StatusNotificationCB(
266 media::cast::transport::CastTransportStatus unused_status) { 201 media::cast::transport::CastTransportStatus unused_status) {
267 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 202 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
268 // TODO(hubbe): Call javascript UDPTransport error function. 203 // TODO(hubbe): Call javascript UDPTransport error function.
269 } 204 }
270 205
271 void CastSessionDelegate::InitializationResultCB( 206 void CastSessionDelegate::InitializationResultCB(
(...skipping 20 matching lines...) Expand all
292 ++it) { 227 ++it) {
293 cast_environment_->Logging()->InsertPacketEvent(it->timestamp, 228 cast_environment_->Logging()->InsertPacketEvent(it->timestamp,
294 it->type, 229 it->type,
295 it->rtp_timestamp, 230 it->rtp_timestamp,
296 it->frame_id, 231 it->frame_id,
297 it->packet_id, 232 it->packet_id,
298 it->max_packet_id, 233 it->max_packet_id,
299 it->size); 234 it->size);
300 } 235 }
301 } 236 }
OLDNEW
« no previous file with comments | « chrome/renderer/media/cast_session_delegate.h ('k') | media/cast/cast.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698