| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "media/cast/logging/stats_event_subscriber.h" |
| 6 |
| 5 #include <stddef.h> | 7 #include <stddef.h> |
| 6 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <utility> |
| 7 | 10 |
| 8 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 9 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 11 #include "base/test/simple_test_tick_clock.h" | 14 #include "base/test/simple_test_tick_clock.h" |
| 12 #include "base/time/tick_clock.h" | 15 #include "base/time/tick_clock.h" |
| 13 #include "base/values.h" | 16 #include "base/values.h" |
| 14 #include "media/cast/cast_environment.h" | 17 #include "media/cast/cast_environment.h" |
| 15 #include "media/cast/logging/logging_defines.h" | 18 #include "media/cast/logging/logging_defines.h" |
| 16 #include "media/cast/logging/stats_event_subscriber.h" | |
| 17 #include "media/cast/test/fake_receiver_time_offset_estimator.h" | 19 #include "media/cast/test/fake_receiver_time_offset_estimator.h" |
| 18 #include "media/cast/test/fake_single_thread_task_runner.h" | 20 #include "media/cast/test/fake_single_thread_task_runner.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 22 |
| 21 namespace { | 23 namespace { |
| 22 const int kReceiverOffsetSecs = 100; | 24 const int kReceiverOffsetSecs = 100; |
| 23 } | 25 } |
| 24 | 26 |
| 25 namespace media { | 27 namespace media { |
| 26 namespace cast { | 28 namespace cast { |
| 27 | 29 |
| 28 class StatsEventSubscriberTest : public ::testing::Test { | 30 class StatsEventSubscriberTest : public ::testing::Test { |
| 29 protected: | 31 protected: |
| 30 StatsEventSubscriberTest() | 32 StatsEventSubscriberTest() |
| 31 : sender_clock_(new base::SimpleTestTickClock()), | 33 : sender_clock_(new base::SimpleTestTickClock()), |
| 32 task_runner_(new test::FakeSingleThreadTaskRunner(sender_clock_)), | 34 task_runner_(new test::FakeSingleThreadTaskRunner(sender_clock_)), |
| 33 cast_environment_(new CastEnvironment( | 35 cast_environment_( |
| 34 scoped_ptr<base::TickClock>(sender_clock_).Pass(), | 36 new CastEnvironment(scoped_ptr<base::TickClock>(sender_clock_), |
| 35 task_runner_, | 37 task_runner_, |
| 36 task_runner_, | 38 task_runner_, |
| 37 task_runner_)), | 39 task_runner_)), |
| 38 fake_offset_estimator_( | 40 fake_offset_estimator_( |
| 39 base::TimeDelta::FromSeconds(kReceiverOffsetSecs)) { | 41 base::TimeDelta::FromSeconds(kReceiverOffsetSecs)) { |
| 40 receiver_clock_.Advance(base::TimeDelta::FromSeconds(kReceiverOffsetSecs)); | 42 receiver_clock_.Advance(base::TimeDelta::FromSeconds(kReceiverOffsetSecs)); |
| 41 cast_environment_->logger()->Subscribe(&fake_offset_estimator_); | 43 cast_environment_->logger()->Subscribe(&fake_offset_estimator_); |
| 42 } | 44 } |
| 43 | 45 |
| 44 ~StatsEventSubscriberTest() override { | 46 ~StatsEventSubscriberTest() override { |
| 45 if (subscriber_.get()) | 47 if (subscriber_.get()) |
| 46 cast_environment_->logger()->Unsubscribe(subscriber_.get()); | 48 cast_environment_->logger()->Unsubscribe(subscriber_.get()); |
| 47 cast_environment_->logger()->Unsubscribe(&fake_offset_estimator_); | 49 cast_environment_->logger()->Unsubscribe(&fake_offset_estimator_); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 78 int num_frames = StatsEventSubscriber::kMaxFrameInfoMapSize + 50; | 80 int num_frames = StatsEventSubscriber::kMaxFrameInfoMapSize + 50; |
| 79 int dropped_frames = 0; | 81 int dropped_frames = 0; |
| 80 base::TimeTicks start_time = sender_clock_->NowTicks(); | 82 base::TimeTicks start_time = sender_clock_->NowTicks(); |
| 81 // Drop half the frames during the encode step. | 83 // Drop half the frames during the encode step. |
| 82 for (int i = 0; i < num_frames; i++) { | 84 for (int i = 0; i < num_frames; i++) { |
| 83 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); | 85 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); |
| 84 capture_begin_event->timestamp = sender_clock_->NowTicks(); | 86 capture_begin_event->timestamp = sender_clock_->NowTicks(); |
| 85 capture_begin_event->type = FRAME_CAPTURE_BEGIN; | 87 capture_begin_event->type = FRAME_CAPTURE_BEGIN; |
| 86 capture_begin_event->media_type = VIDEO_EVENT; | 88 capture_begin_event->media_type = VIDEO_EVENT; |
| 87 capture_begin_event->rtp_timestamp = rtp_timestamp; | 89 capture_begin_event->rtp_timestamp = rtp_timestamp; |
| 88 cast_environment_->logger()->DispatchFrameEvent(capture_begin_event.Pass()); | 90 cast_environment_->logger()->DispatchFrameEvent( |
| 91 std::move(capture_begin_event)); |
| 89 | 92 |
| 90 AdvanceClocks(base::TimeDelta::FromMicroseconds(10)); | 93 AdvanceClocks(base::TimeDelta::FromMicroseconds(10)); |
| 91 scoped_ptr<FrameEvent> capture_end_event(new FrameEvent()); | 94 scoped_ptr<FrameEvent> capture_end_event(new FrameEvent()); |
| 92 capture_end_event->timestamp = sender_clock_->NowTicks(); | 95 capture_end_event->timestamp = sender_clock_->NowTicks(); |
| 93 capture_end_event->type = FRAME_CAPTURE_END; | 96 capture_end_event->type = FRAME_CAPTURE_END; |
| 94 capture_end_event->media_type = VIDEO_EVENT; | 97 capture_end_event->media_type = VIDEO_EVENT; |
| 95 capture_end_event->rtp_timestamp = rtp_timestamp; | 98 capture_end_event->rtp_timestamp = rtp_timestamp; |
| 96 cast_environment_->logger()->DispatchFrameEvent(capture_end_event.Pass()); | 99 cast_environment_->logger()->DispatchFrameEvent( |
| 100 std::move(capture_end_event)); |
| 97 | 101 |
| 98 if (i % 2 == 0) { | 102 if (i % 2 == 0) { |
| 99 AdvanceClocks(base::TimeDelta::FromMicroseconds(10)); | 103 AdvanceClocks(base::TimeDelta::FromMicroseconds(10)); |
| 100 scoped_ptr<FrameEvent> encode_event(new FrameEvent()); | 104 scoped_ptr<FrameEvent> encode_event(new FrameEvent()); |
| 101 encode_event->timestamp = sender_clock_->NowTicks(); | 105 encode_event->timestamp = sender_clock_->NowTicks(); |
| 102 encode_event->type = FRAME_ENCODED; | 106 encode_event->type = FRAME_ENCODED; |
| 103 encode_event->media_type = VIDEO_EVENT; | 107 encode_event->media_type = VIDEO_EVENT; |
| 104 encode_event->rtp_timestamp = rtp_timestamp; | 108 encode_event->rtp_timestamp = rtp_timestamp; |
| 105 encode_event->frame_id = frame_id; | 109 encode_event->frame_id = frame_id; |
| 106 encode_event->size = 1024; | 110 encode_event->size = 1024; |
| 107 encode_event->key_frame = true; | 111 encode_event->key_frame = true; |
| 108 encode_event->target_bitrate = 5678; | 112 encode_event->target_bitrate = 5678; |
| 109 encode_event->encoder_cpu_utilization = 9.10; | 113 encode_event->encoder_cpu_utilization = 9.10; |
| 110 encode_event->idealized_bitrate_utilization = 11.12; | 114 encode_event->idealized_bitrate_utilization = 11.12; |
| 111 cast_environment_->logger()->DispatchFrameEvent(encode_event.Pass()); | 115 cast_environment_->logger()->DispatchFrameEvent(std::move(encode_event)); |
| 112 } else if (i < extra_frames) { | 116 } else if (i < extra_frames) { |
| 113 dropped_frames++; | 117 dropped_frames++; |
| 114 } | 118 } |
| 115 AdvanceClocks(base::TimeDelta::FromMicroseconds(34567)); | 119 AdvanceClocks(base::TimeDelta::FromMicroseconds(34567)); |
| 116 rtp_timestamp += 90; | 120 rtp_timestamp += 90; |
| 117 frame_id++; | 121 frame_id++; |
| 118 } | 122 } |
| 119 | 123 |
| 120 base::TimeTicks end_time = sender_clock_->NowTicks(); | 124 base::TimeTicks end_time = sender_clock_->NowTicks(); |
| 121 | 125 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 encode_event->timestamp = sender_clock_->NowTicks(); | 169 encode_event->timestamp = sender_clock_->NowTicks(); |
| 166 encode_event->type = FRAME_ENCODED; | 170 encode_event->type = FRAME_ENCODED; |
| 167 encode_event->media_type = VIDEO_EVENT; | 171 encode_event->media_type = VIDEO_EVENT; |
| 168 encode_event->rtp_timestamp = rtp_timestamp; | 172 encode_event->rtp_timestamp = rtp_timestamp; |
| 169 encode_event->frame_id = frame_id; | 173 encode_event->frame_id = frame_id; |
| 170 encode_event->size = size; | 174 encode_event->size = size; |
| 171 encode_event->key_frame = true; | 175 encode_event->key_frame = true; |
| 172 encode_event->target_bitrate = 5678; | 176 encode_event->target_bitrate = 5678; |
| 173 encode_event->encoder_cpu_utilization = 9.10; | 177 encode_event->encoder_cpu_utilization = 9.10; |
| 174 encode_event->idealized_bitrate_utilization = 11.12; | 178 encode_event->idealized_bitrate_utilization = 11.12; |
| 175 cast_environment_->logger()->DispatchFrameEvent(encode_event.Pass()); | 179 cast_environment_->logger()->DispatchFrameEvent(std::move(encode_event)); |
| 176 last_event_time = sender_clock_->NowTicks(); | 180 last_event_time = sender_clock_->NowTicks(); |
| 177 | 181 |
| 178 AdvanceClocks(base::TimeDelta::FromMicroseconds(35678)); | 182 AdvanceClocks(base::TimeDelta::FromMicroseconds(35678)); |
| 179 rtp_timestamp += 90; | 183 rtp_timestamp += 90; |
| 180 frame_id++; | 184 frame_id++; |
| 181 } | 185 } |
| 182 | 186 |
| 183 base::TimeTicks end_time = sender_clock_->NowTicks(); | 187 base::TimeTicks end_time = sender_clock_->NowTicks(); |
| 184 | 188 |
| 185 StatsEventSubscriber::StatsMap stats_map; | 189 StatsEventSubscriber::StatsMap stats_map; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 uint32_t frame_id = 0; | 226 uint32_t frame_id = 0; |
| 223 int num_frames = 10; | 227 int num_frames = 10; |
| 224 base::TimeTicks start_time = sender_clock_->NowTicks(); | 228 base::TimeTicks start_time = sender_clock_->NowTicks(); |
| 225 for (int i = 0; i < num_frames; i++) { | 229 for (int i = 0; i < num_frames; i++) { |
| 226 scoped_ptr<FrameEvent> decode_event(new FrameEvent()); | 230 scoped_ptr<FrameEvent> decode_event(new FrameEvent()); |
| 227 decode_event->timestamp = receiver_clock_.NowTicks(); | 231 decode_event->timestamp = receiver_clock_.NowTicks(); |
| 228 decode_event->type = FRAME_DECODED; | 232 decode_event->type = FRAME_DECODED; |
| 229 decode_event->media_type = VIDEO_EVENT; | 233 decode_event->media_type = VIDEO_EVENT; |
| 230 decode_event->rtp_timestamp = rtp_timestamp; | 234 decode_event->rtp_timestamp = rtp_timestamp; |
| 231 decode_event->frame_id = frame_id; | 235 decode_event->frame_id = frame_id; |
| 232 cast_environment_->logger()->DispatchFrameEvent(decode_event.Pass()); | 236 cast_environment_->logger()->DispatchFrameEvent(std::move(decode_event)); |
| 233 | 237 |
| 234 AdvanceClocks(base::TimeDelta::FromMicroseconds(36789)); | 238 AdvanceClocks(base::TimeDelta::FromMicroseconds(36789)); |
| 235 rtp_timestamp += 90; | 239 rtp_timestamp += 90; |
| 236 frame_id++; | 240 frame_id++; |
| 237 } | 241 } |
| 238 | 242 |
| 239 base::TimeTicks end_time = sender_clock_->NowTicks(); | 243 base::TimeTicks end_time = sender_clock_->NowTicks(); |
| 240 | 244 |
| 241 StatsEventSubscriber::StatsMap stats_map; | 245 StatsEventSubscriber::StatsMap stats_map; |
| 242 subscriber_->GetStatsInternal(&stats_map); | 246 subscriber_->GetStatsInternal(&stats_map); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 262 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(delay_ms); | 266 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(delay_ms); |
| 263 if (delay_ms > 0) | 267 if (delay_ms > 0) |
| 264 late_frames++; | 268 late_frames++; |
| 265 scoped_ptr<FrameEvent> playout_event(new FrameEvent()); | 269 scoped_ptr<FrameEvent> playout_event(new FrameEvent()); |
| 266 playout_event->timestamp = receiver_clock_.NowTicks(); | 270 playout_event->timestamp = receiver_clock_.NowTicks(); |
| 267 playout_event->type = FRAME_PLAYOUT; | 271 playout_event->type = FRAME_PLAYOUT; |
| 268 playout_event->media_type = VIDEO_EVENT; | 272 playout_event->media_type = VIDEO_EVENT; |
| 269 playout_event->rtp_timestamp = rtp_timestamp; | 273 playout_event->rtp_timestamp = rtp_timestamp; |
| 270 playout_event->frame_id = frame_id; | 274 playout_event->frame_id = frame_id; |
| 271 playout_event->delay_delta = delay; | 275 playout_event->delay_delta = delay; |
| 272 cast_environment_->logger()->DispatchFrameEvent(playout_event.Pass()); | 276 cast_environment_->logger()->DispatchFrameEvent(std::move(playout_event)); |
| 273 | 277 |
| 274 AdvanceClocks(base::TimeDelta::FromMicroseconds(37890)); | 278 AdvanceClocks(base::TimeDelta::FromMicroseconds(37890)); |
| 275 rtp_timestamp += 90; | 279 rtp_timestamp += 90; |
| 276 frame_id++; | 280 frame_id++; |
| 277 } | 281 } |
| 278 | 282 |
| 279 StatsEventSubscriber::StatsMap stats_map; | 283 StatsEventSubscriber::StatsMap stats_map; |
| 280 subscriber_->GetStatsInternal(&stats_map); | 284 subscriber_->GetStatsInternal(&stats_map); |
| 281 | 285 |
| 282 StatsEventSubscriber::StatsMap::iterator it = stats_map.find( | 286 StatsEventSubscriber::StatsMap::iterator it = stats_map.find( |
| 283 StatsEventSubscriber::NUM_FRAMES_LATE); | 287 StatsEventSubscriber::NUM_FRAMES_LATE); |
| 284 ASSERT_TRUE(it != stats_map.end()); | 288 ASSERT_TRUE(it != stats_map.end()); |
| 285 | 289 |
| 286 EXPECT_DOUBLE_EQ(it->second, late_frames); | 290 EXPECT_DOUBLE_EQ(it->second, late_frames); |
| 287 } | 291 } |
| 288 | 292 |
| 289 TEST_F(StatsEventSubscriberTest, E2ELatency) { | 293 TEST_F(StatsEventSubscriberTest, E2ELatency) { |
| 290 Init(VIDEO_EVENT); | 294 Init(VIDEO_EVENT); |
| 291 | 295 |
| 292 uint32_t rtp_timestamp = 0; | 296 uint32_t rtp_timestamp = 0; |
| 293 uint32_t frame_id = 0; | 297 uint32_t frame_id = 0; |
| 294 int num_frames = 10; | 298 int num_frames = 10; |
| 295 base::TimeDelta total_latency; | 299 base::TimeDelta total_latency; |
| 296 for (int i = 0; i < num_frames; i++) { | 300 for (int i = 0; i < num_frames; i++) { |
| 297 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); | 301 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); |
| 298 capture_begin_event->timestamp = sender_clock_->NowTicks(); | 302 capture_begin_event->timestamp = sender_clock_->NowTicks(); |
| 299 capture_begin_event->type = FRAME_CAPTURE_BEGIN; | 303 capture_begin_event->type = FRAME_CAPTURE_BEGIN; |
| 300 capture_begin_event->media_type = VIDEO_EVENT; | 304 capture_begin_event->media_type = VIDEO_EVENT; |
| 301 capture_begin_event->rtp_timestamp = rtp_timestamp; | 305 capture_begin_event->rtp_timestamp = rtp_timestamp; |
| 302 cast_environment_->logger()->DispatchFrameEvent(capture_begin_event.Pass()); | 306 cast_environment_->logger()->DispatchFrameEvent( |
| 307 std::move(capture_begin_event)); |
| 303 | 308 |
| 304 int latency_micros = 100000 + base::RandInt(-5000, 50000); | 309 int latency_micros = 100000 + base::RandInt(-5000, 50000); |
| 305 base::TimeDelta latency = base::TimeDelta::FromMicroseconds(latency_micros); | 310 base::TimeDelta latency = base::TimeDelta::FromMicroseconds(latency_micros); |
| 306 AdvanceClocks(latency); | 311 AdvanceClocks(latency); |
| 307 | 312 |
| 308 int delay_micros = base::RandInt(-50000, 50000); | 313 int delay_micros = base::RandInt(-50000, 50000); |
| 309 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(delay_micros); | 314 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(delay_micros); |
| 310 total_latency += latency; | 315 total_latency += latency; |
| 311 | 316 |
| 312 scoped_ptr<FrameEvent> playout_event(new FrameEvent()); | 317 scoped_ptr<FrameEvent> playout_event(new FrameEvent()); |
| 313 playout_event->timestamp = receiver_clock_.NowTicks(); | 318 playout_event->timestamp = receiver_clock_.NowTicks(); |
| 314 playout_event->type = FRAME_PLAYOUT; | 319 playout_event->type = FRAME_PLAYOUT; |
| 315 playout_event->media_type = VIDEO_EVENT; | 320 playout_event->media_type = VIDEO_EVENT; |
| 316 playout_event->rtp_timestamp = rtp_timestamp; | 321 playout_event->rtp_timestamp = rtp_timestamp; |
| 317 playout_event->frame_id = frame_id; | 322 playout_event->frame_id = frame_id; |
| 318 playout_event->delay_delta = delay; | 323 playout_event->delay_delta = delay; |
| 319 cast_environment_->logger()->DispatchFrameEvent(playout_event.Pass()); | 324 cast_environment_->logger()->DispatchFrameEvent(std::move(playout_event)); |
| 320 | 325 |
| 321 rtp_timestamp += 90; | 326 rtp_timestamp += 90; |
| 322 frame_id++; | 327 frame_id++; |
| 323 } | 328 } |
| 324 | 329 |
| 325 StatsEventSubscriber::StatsMap stats_map; | 330 StatsEventSubscriber::StatsMap stats_map; |
| 326 subscriber_->GetStatsInternal(&stats_map); | 331 subscriber_->GetStatsInternal(&stats_map); |
| 327 | 332 |
| 328 StatsEventSubscriber::StatsMap::iterator it = | 333 StatsEventSubscriber::StatsMap::iterator it = |
| 329 stats_map.find(StatsEventSubscriber::AVG_E2E_LATENCY_MS); | 334 stats_map.find(StatsEventSubscriber::AVG_E2E_LATENCY_MS); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 351 int num_packets_rtx_rejected = 0; | 356 int num_packets_rtx_rejected = 0; |
| 352 | 357 |
| 353 base::TimeTicks sender_encoded_time = sender_clock_->NowTicks(); | 358 base::TimeTicks sender_encoded_time = sender_clock_->NowTicks(); |
| 354 base::TimeTicks receiver_encoded_time = receiver_clock_.NowTicks(); | 359 base::TimeTicks receiver_encoded_time = receiver_clock_.NowTicks(); |
| 355 scoped_ptr<FrameEvent> encode_event(new FrameEvent()); | 360 scoped_ptr<FrameEvent> encode_event(new FrameEvent()); |
| 356 encode_event->timestamp = sender_encoded_time; | 361 encode_event->timestamp = sender_encoded_time; |
| 357 encode_event->type = FRAME_ENCODED; | 362 encode_event->type = FRAME_ENCODED; |
| 358 encode_event->media_type = VIDEO_EVENT; | 363 encode_event->media_type = VIDEO_EVENT; |
| 359 encode_event->rtp_timestamp = rtp_timestamp; | 364 encode_event->rtp_timestamp = rtp_timestamp; |
| 360 encode_event->frame_id = 0; | 365 encode_event->frame_id = 0; |
| 361 cast_environment_->logger()->DispatchFrameEvent(encode_event.Pass()); | 366 cast_environment_->logger()->DispatchFrameEvent(std::move(encode_event)); |
| 362 | 367 |
| 363 // Every 2nd packet will be retransmitted once. | 368 // Every 2nd packet will be retransmitted once. |
| 364 // Every 4th packet will be retransmitted twice. | 369 // Every 4th packet will be retransmitted twice. |
| 365 // Every 8th packet will be retransmitted 3 times + 1 rejected retransmission. | 370 // Every 8th packet will be retransmitted 3 times + 1 rejected retransmission. |
| 366 for (int i = 0; i < num_packets; i++) { | 371 for (int i = 0; i < num_packets; i++) { |
| 367 int size = 1000 + base::RandInt(-100, 100); | 372 int size = 1000 + base::RandInt(-100, 100); |
| 368 total_size += size; | 373 total_size += size; |
| 369 | 374 |
| 370 scoped_ptr<PacketEvent> send_event(new PacketEvent()); | 375 scoped_ptr<PacketEvent> send_event(new PacketEvent()); |
| 371 send_event->timestamp = sender_clock_->NowTicks(); | 376 send_event->timestamp = sender_clock_->NowTicks(); |
| 372 send_event->type = PACKET_SENT_TO_NETWORK; | 377 send_event->type = PACKET_SENT_TO_NETWORK; |
| 373 send_event->media_type = VIDEO_EVENT; | 378 send_event->media_type = VIDEO_EVENT; |
| 374 send_event->rtp_timestamp = rtp_timestamp; | 379 send_event->rtp_timestamp = rtp_timestamp; |
| 375 send_event->frame_id = 0; | 380 send_event->frame_id = 0; |
| 376 send_event->packet_id = i; | 381 send_event->packet_id = i; |
| 377 send_event->max_packet_id = num_packets - 1; | 382 send_event->max_packet_id = num_packets - 1; |
| 378 send_event->size = size; | 383 send_event->size = size; |
| 379 cast_environment_->logger()->DispatchPacketEvent(send_event.Pass()); | 384 cast_environment_->logger()->DispatchPacketEvent(std::move(send_event)); |
| 380 | 385 |
| 381 num_packets_transmitted++; | 386 num_packets_transmitted++; |
| 382 total_queueing_latency += sender_clock_->NowTicks() - sender_encoded_time; | 387 total_queueing_latency += sender_clock_->NowTicks() - sender_encoded_time; |
| 383 | 388 |
| 384 int latency_micros = 20000 + base::RandInt(-10000, 10000); | 389 int latency_micros = 20000 + base::RandInt(-10000, 10000); |
| 385 base::TimeDelta latency = base::TimeDelta::FromMicroseconds(latency_micros); | 390 base::TimeDelta latency = base::TimeDelta::FromMicroseconds(latency_micros); |
| 386 // Latency is only recorded for packets that aren't retransmitted. | 391 // Latency is only recorded for packets that aren't retransmitted. |
| 387 if (i % 2 != 0) { | 392 if (i % 2 != 0) { |
| 388 total_network_latency += latency; | 393 total_network_latency += latency; |
| 389 total_packet_latency += | 394 total_packet_latency += |
| (...skipping 10 matching lines...) Expand all Loading... |
| 400 if (i % 2 == 0) { | 405 if (i % 2 == 0) { |
| 401 scoped_ptr<PacketEvent> retransmit_event(new PacketEvent()); | 406 scoped_ptr<PacketEvent> retransmit_event(new PacketEvent()); |
| 402 retransmit_event->timestamp = receiver_clock_.NowTicks(); | 407 retransmit_event->timestamp = receiver_clock_.NowTicks(); |
| 403 retransmit_event->type = PACKET_RETRANSMITTED; | 408 retransmit_event->type = PACKET_RETRANSMITTED; |
| 404 retransmit_event->media_type = VIDEO_EVENT; | 409 retransmit_event->media_type = VIDEO_EVENT; |
| 405 retransmit_event->rtp_timestamp = rtp_timestamp; | 410 retransmit_event->rtp_timestamp = rtp_timestamp; |
| 406 retransmit_event->frame_id = 0; | 411 retransmit_event->frame_id = 0; |
| 407 retransmit_event->packet_id = i; | 412 retransmit_event->packet_id = i; |
| 408 retransmit_event->max_packet_id = num_packets - 1; | 413 retransmit_event->max_packet_id = num_packets - 1; |
| 409 retransmit_event->size = size; | 414 retransmit_event->size = size; |
| 410 cast_environment_->logger()->DispatchPacketEvent(retransmit_event.Pass()); | 415 cast_environment_->logger()->DispatchPacketEvent( |
| 416 std::move(retransmit_event)); |
| 411 | 417 |
| 412 retransmit_total_size += size; | 418 retransmit_total_size += size; |
| 413 num_packets_transmitted++; | 419 num_packets_transmitted++; |
| 414 num_packets_retransmitted++; | 420 num_packets_retransmitted++; |
| 415 } | 421 } |
| 416 | 422 |
| 417 // Retransmission 2. | 423 // Retransmission 2. |
| 418 AdvanceClocks(base::TimeDelta::FromMicroseconds(13456)); | 424 AdvanceClocks(base::TimeDelta::FromMicroseconds(13456)); |
| 419 if (i % 4 == 0) { | 425 if (i % 4 == 0) { |
| 420 scoped_ptr<PacketEvent> retransmit_event(new PacketEvent()); | 426 scoped_ptr<PacketEvent> retransmit_event(new PacketEvent()); |
| 421 retransmit_event->timestamp = receiver_clock_.NowTicks(); | 427 retransmit_event->timestamp = receiver_clock_.NowTicks(); |
| 422 retransmit_event->type = PACKET_RETRANSMITTED; | 428 retransmit_event->type = PACKET_RETRANSMITTED; |
| 423 retransmit_event->media_type = VIDEO_EVENT; | 429 retransmit_event->media_type = VIDEO_EVENT; |
| 424 retransmit_event->rtp_timestamp = rtp_timestamp; | 430 retransmit_event->rtp_timestamp = rtp_timestamp; |
| 425 retransmit_event->frame_id = 0; | 431 retransmit_event->frame_id = 0; |
| 426 retransmit_event->packet_id = i; | 432 retransmit_event->packet_id = i; |
| 427 retransmit_event->max_packet_id = num_packets - 1; | 433 retransmit_event->max_packet_id = num_packets - 1; |
| 428 retransmit_event->size = size; | 434 retransmit_event->size = size; |
| 429 cast_environment_->logger()->DispatchPacketEvent(retransmit_event.Pass()); | 435 cast_environment_->logger()->DispatchPacketEvent( |
| 436 std::move(retransmit_event)); |
| 430 | 437 |
| 431 retransmit_total_size += size; | 438 retransmit_total_size += size; |
| 432 num_packets_transmitted++; | 439 num_packets_transmitted++; |
| 433 num_packets_retransmitted++; | 440 num_packets_retransmitted++; |
| 434 } | 441 } |
| 435 | 442 |
| 436 // Retransmission 3. | 443 // Retransmission 3. |
| 437 AdvanceClocks(base::TimeDelta::FromMicroseconds(14567)); | 444 AdvanceClocks(base::TimeDelta::FromMicroseconds(14567)); |
| 438 if (i % 8 == 0) { | 445 if (i % 8 == 0) { |
| 439 scoped_ptr<PacketEvent> retransmit_event(new PacketEvent()); | 446 scoped_ptr<PacketEvent> retransmit_event(new PacketEvent()); |
| 440 retransmit_event->timestamp = receiver_clock_.NowTicks(); | 447 retransmit_event->timestamp = receiver_clock_.NowTicks(); |
| 441 retransmit_event->type = PACKET_RETRANSMITTED; | 448 retransmit_event->type = PACKET_RETRANSMITTED; |
| 442 retransmit_event->media_type = VIDEO_EVENT; | 449 retransmit_event->media_type = VIDEO_EVENT; |
| 443 retransmit_event->rtp_timestamp = rtp_timestamp; | 450 retransmit_event->rtp_timestamp = rtp_timestamp; |
| 444 retransmit_event->frame_id = 0; | 451 retransmit_event->frame_id = 0; |
| 445 retransmit_event->packet_id = i; | 452 retransmit_event->packet_id = i; |
| 446 retransmit_event->max_packet_id = num_packets - 1; | 453 retransmit_event->max_packet_id = num_packets - 1; |
| 447 retransmit_event->size = size; | 454 retransmit_event->size = size; |
| 448 cast_environment_->logger()->DispatchPacketEvent(retransmit_event.Pass()); | 455 cast_environment_->logger()->DispatchPacketEvent( |
| 456 std::move(retransmit_event)); |
| 449 | 457 |
| 450 scoped_ptr<PacketEvent> reject_event(new PacketEvent()); | 458 scoped_ptr<PacketEvent> reject_event(new PacketEvent()); |
| 451 reject_event->timestamp = receiver_clock_.NowTicks(); | 459 reject_event->timestamp = receiver_clock_.NowTicks(); |
| 452 reject_event->type = PACKET_RTX_REJECTED; | 460 reject_event->type = PACKET_RTX_REJECTED; |
| 453 reject_event->media_type = VIDEO_EVENT; | 461 reject_event->media_type = VIDEO_EVENT; |
| 454 reject_event->rtp_timestamp = rtp_timestamp; | 462 reject_event->rtp_timestamp = rtp_timestamp; |
| 455 reject_event->frame_id = 0; | 463 reject_event->frame_id = 0; |
| 456 reject_event->packet_id = i; | 464 reject_event->packet_id = i; |
| 457 reject_event->max_packet_id = num_packets - 1; | 465 reject_event->max_packet_id = num_packets - 1; |
| 458 reject_event->size = size; | 466 reject_event->size = size; |
| 459 cast_environment_->logger()->DispatchPacketEvent(reject_event.Pass()); | 467 cast_environment_->logger()->DispatchPacketEvent(std::move(reject_event)); |
| 460 | 468 |
| 461 retransmit_total_size += size; | 469 retransmit_total_size += size; |
| 462 num_packets_transmitted++; | 470 num_packets_transmitted++; |
| 463 num_packets_retransmitted++; | 471 num_packets_retransmitted++; |
| 464 num_packets_rtx_rejected++; | 472 num_packets_rtx_rejected++; |
| 465 } | 473 } |
| 466 | 474 |
| 467 scoped_ptr<PacketEvent> receive_event(new PacketEvent()); | 475 scoped_ptr<PacketEvent> receive_event(new PacketEvent()); |
| 468 receive_event->timestamp = received_time; | 476 receive_event->timestamp = received_time; |
| 469 receive_event->type = PACKET_RECEIVED; | 477 receive_event->type = PACKET_RECEIVED; |
| 470 receive_event->media_type = VIDEO_EVENT; | 478 receive_event->media_type = VIDEO_EVENT; |
| 471 receive_event->rtp_timestamp = rtp_timestamp; | 479 receive_event->rtp_timestamp = rtp_timestamp; |
| 472 receive_event->frame_id = 0; | 480 receive_event->frame_id = 0; |
| 473 receive_event->packet_id = i; | 481 receive_event->packet_id = i; |
| 474 receive_event->max_packet_id = num_packets - 1; | 482 receive_event->max_packet_id = num_packets - 1; |
| 475 receive_event->size = size; | 483 receive_event->size = size; |
| 476 cast_environment_->logger()->DispatchPacketEvent(receive_event.Pass()); | 484 cast_environment_->logger()->DispatchPacketEvent(std::move(receive_event)); |
| 477 | 485 |
| 478 num_packets_received++; | 486 num_packets_received++; |
| 479 } | 487 } |
| 480 | 488 |
| 481 base::TimeTicks end_time = sender_clock_->NowTicks(); | 489 base::TimeTicks end_time = sender_clock_->NowTicks(); |
| 482 base::TimeDelta duration = end_time - start_time; | 490 base::TimeDelta duration = end_time - start_time; |
| 483 | 491 |
| 484 StatsEventSubscriber::StatsMap stats_map; | 492 StatsEventSubscriber::StatsMap stats_map; |
| 485 subscriber_->GetStatsInternal(&stats_map); | 493 subscriber_->GetStatsInternal(&stats_map); |
| 486 | 494 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 // 10 Frames with encode time in the bucket of "15-19"ms. | 575 // 10 Frames with encode time in the bucket of "15-19"ms. |
| 568 for (int i = 0; i < 10; ++i) { | 576 for (int i = 0; i < 10; ++i) { |
| 569 ++frame_id; | 577 ++frame_id; |
| 570 ++rtp_timestamp; | 578 ++rtp_timestamp; |
| 571 | 579 |
| 572 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); | 580 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); |
| 573 capture_begin_event->timestamp = sender_clock_->NowTicks(); | 581 capture_begin_event->timestamp = sender_clock_->NowTicks(); |
| 574 capture_begin_event->type = FRAME_CAPTURE_BEGIN; | 582 capture_begin_event->type = FRAME_CAPTURE_BEGIN; |
| 575 capture_begin_event->media_type = VIDEO_EVENT; | 583 capture_begin_event->media_type = VIDEO_EVENT; |
| 576 capture_begin_event->rtp_timestamp = rtp_timestamp; | 584 capture_begin_event->rtp_timestamp = rtp_timestamp; |
| 577 cast_environment_->logger()->DispatchFrameEvent(capture_begin_event.Pass()); | 585 cast_environment_->logger()->DispatchFrameEvent( |
| 586 std::move(capture_begin_event)); |
| 578 | 587 |
| 579 AdvanceClocks(base::TimeDelta::FromMilliseconds(10)); | 588 AdvanceClocks(base::TimeDelta::FromMilliseconds(10)); |
| 580 scoped_ptr<FrameEvent> capture_end_event(new FrameEvent()); | 589 scoped_ptr<FrameEvent> capture_end_event(new FrameEvent()); |
| 581 capture_end_event->timestamp = sender_clock_->NowTicks(); | 590 capture_end_event->timestamp = sender_clock_->NowTicks(); |
| 582 capture_end_event->type = FRAME_CAPTURE_END; | 591 capture_end_event->type = FRAME_CAPTURE_END; |
| 583 capture_end_event->media_type = VIDEO_EVENT; | 592 capture_end_event->media_type = VIDEO_EVENT; |
| 584 capture_end_event->rtp_timestamp = rtp_timestamp; | 593 capture_end_event->rtp_timestamp = rtp_timestamp; |
| 585 cast_environment_->logger()->DispatchFrameEvent(capture_end_event.Pass()); | 594 cast_environment_->logger()->DispatchFrameEvent( |
| 595 std::move(capture_end_event)); |
| 586 | 596 |
| 587 AdvanceClocks(base::TimeDelta::FromMilliseconds(15)); | 597 AdvanceClocks(base::TimeDelta::FromMilliseconds(15)); |
| 588 scoped_ptr<FrameEvent> encode_event(new FrameEvent()); | 598 scoped_ptr<FrameEvent> encode_event(new FrameEvent()); |
| 589 encode_event->timestamp = sender_clock_->NowTicks(); | 599 encode_event->timestamp = sender_clock_->NowTicks(); |
| 590 encode_event->type = FRAME_ENCODED; | 600 encode_event->type = FRAME_ENCODED; |
| 591 encode_event->media_type = VIDEO_EVENT; | 601 encode_event->media_type = VIDEO_EVENT; |
| 592 encode_event->rtp_timestamp = rtp_timestamp; | 602 encode_event->rtp_timestamp = rtp_timestamp; |
| 593 encode_event->frame_id = frame_id; | 603 encode_event->frame_id = frame_id; |
| 594 encode_event->size = 1024; | 604 encode_event->size = 1024; |
| 595 encode_event->key_frame = true; | 605 encode_event->key_frame = true; |
| 596 encode_event->target_bitrate = 5678; | 606 encode_event->target_bitrate = 5678; |
| 597 encode_event->encoder_cpu_utilization = 9.10; | 607 encode_event->encoder_cpu_utilization = 9.10; |
| 598 encode_event->idealized_bitrate_utilization = 11.12; | 608 encode_event->idealized_bitrate_utilization = 11.12; |
| 599 cast_environment_->logger()->DispatchFrameEvent(encode_event.Pass()); | 609 cast_environment_->logger()->DispatchFrameEvent(std::move(encode_event)); |
| 600 } | 610 } |
| 601 | 611 |
| 602 // Send 3 packets for the last frame. | 612 // Send 3 packets for the last frame. |
| 603 // Queueing latencies are 100ms, 200ms and 300ms. | 613 // Queueing latencies are 100ms, 200ms and 300ms. |
| 604 for (int i = 0; i < 3; ++i) { | 614 for (int i = 0; i < 3; ++i) { |
| 605 AdvanceClocks(base::TimeDelta::FromMilliseconds(100)); | 615 AdvanceClocks(base::TimeDelta::FromMilliseconds(100)); |
| 606 scoped_ptr<PacketEvent> send_event(new PacketEvent()); | 616 scoped_ptr<PacketEvent> send_event(new PacketEvent()); |
| 607 send_event->timestamp = sender_clock_->NowTicks(); | 617 send_event->timestamp = sender_clock_->NowTicks(); |
| 608 send_event->type = PACKET_SENT_TO_NETWORK; | 618 send_event->type = PACKET_SENT_TO_NETWORK; |
| 609 send_event->media_type = VIDEO_EVENT; | 619 send_event->media_type = VIDEO_EVENT; |
| 610 send_event->rtp_timestamp = rtp_timestamp; | 620 send_event->rtp_timestamp = rtp_timestamp; |
| 611 send_event->frame_id = 0; | 621 send_event->frame_id = 0; |
| 612 send_event->packet_id = i; | 622 send_event->packet_id = i; |
| 613 send_event->max_packet_id = 2; | 623 send_event->max_packet_id = 2; |
| 614 send_event->size = 123; | 624 send_event->size = 123; |
| 615 cast_environment_->logger()->DispatchPacketEvent(send_event.Pass()); | 625 cast_environment_->logger()->DispatchPacketEvent(std::move(send_event)); |
| 616 } | 626 } |
| 617 | 627 |
| 618 // Receive 3 packets for the last frame. | 628 // Receive 3 packets for the last frame. |
| 619 // Network latencies are 100ms, 200ms and 300ms. | 629 // Network latencies are 100ms, 200ms and 300ms. |
| 620 // Packet latencies are 400ms. | 630 // Packet latencies are 400ms. |
| 621 AdvanceClocks(base::TimeDelta::FromMilliseconds(100)); | 631 AdvanceClocks(base::TimeDelta::FromMilliseconds(100)); |
| 622 for (int i = 0; i < 3; ++i) { | 632 for (int i = 0; i < 3; ++i) { |
| 623 scoped_ptr<PacketEvent> receive_event(new PacketEvent()); | 633 scoped_ptr<PacketEvent> receive_event(new PacketEvent()); |
| 624 receive_event->timestamp = receiver_clock_.NowTicks(); | 634 receive_event->timestamp = receiver_clock_.NowTicks(); |
| 625 receive_event->type = PACKET_RECEIVED; | 635 receive_event->type = PACKET_RECEIVED; |
| 626 receive_event->media_type = VIDEO_EVENT; | 636 receive_event->media_type = VIDEO_EVENT; |
| 627 receive_event->rtp_timestamp = rtp_timestamp; | 637 receive_event->rtp_timestamp = rtp_timestamp; |
| 628 receive_event->frame_id = 0; | 638 receive_event->frame_id = 0; |
| 629 receive_event->packet_id = i; | 639 receive_event->packet_id = i; |
| 630 receive_event->max_packet_id = 2; | 640 receive_event->max_packet_id = 2; |
| 631 receive_event->size = 123; | 641 receive_event->size = 123; |
| 632 cast_environment_->logger()->DispatchPacketEvent(receive_event.Pass()); | 642 cast_environment_->logger()->DispatchPacketEvent(std::move(receive_event)); |
| 633 } | 643 } |
| 634 | 644 |
| 635 scoped_ptr<FrameEvent> playout_event(new FrameEvent()); | 645 scoped_ptr<FrameEvent> playout_event(new FrameEvent()); |
| 636 playout_event->timestamp = receiver_clock_.NowTicks(); | 646 playout_event->timestamp = receiver_clock_.NowTicks(); |
| 637 playout_event->type = FRAME_PLAYOUT; | 647 playout_event->type = FRAME_PLAYOUT; |
| 638 playout_event->media_type = VIDEO_EVENT; | 648 playout_event->media_type = VIDEO_EVENT; |
| 639 playout_event->rtp_timestamp = rtp_timestamp; | 649 playout_event->rtp_timestamp = rtp_timestamp; |
| 640 playout_event->frame_id = frame_id; | 650 playout_event->frame_id = frame_id; |
| 641 playout_event->delay_delta = base::TimeDelta::FromMilliseconds(100); | 651 playout_event->delay_delta = base::TimeDelta::FromMilliseconds(100); |
| 642 cast_environment_->logger()->DispatchFrameEvent(playout_event.Pass()); | 652 cast_environment_->logger()->DispatchFrameEvent(std::move(playout_event)); |
| 643 | 653 |
| 644 StatsEventSubscriber::SimpleHistogram* histogram; | 654 StatsEventSubscriber::SimpleHistogram* histogram; |
| 645 scoped_ptr<base::ListValue> values; | 655 scoped_ptr<base::ListValue> values; |
| 646 | 656 |
| 647 histogram = subscriber_->GetHistogramForTesting( | 657 histogram = subscriber_->GetHistogramForTesting( |
| 648 StatsEventSubscriber::CAPTURE_LATENCY_MS_HISTO); | 658 StatsEventSubscriber::CAPTURE_LATENCY_MS_HISTO); |
| 649 ASSERT_TRUE(histogram); | 659 ASSERT_TRUE(histogram); |
| 650 values = histogram->GetHistogram().Pass(); | 660 values = histogram->GetHistogram(); |
| 651 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "10-14", 10)); | 661 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "10-14", 10)); |
| 652 | 662 |
| 653 histogram = subscriber_->GetHistogramForTesting( | 663 histogram = subscriber_->GetHistogramForTesting( |
| 654 StatsEventSubscriber::ENCODE_TIME_MS_HISTO); | 664 StatsEventSubscriber::ENCODE_TIME_MS_HISTO); |
| 655 ASSERT_TRUE(histogram); | 665 ASSERT_TRUE(histogram); |
| 656 values = histogram->GetHistogram().Pass(); | 666 values = histogram->GetHistogram(); |
| 657 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "15-19", 10)); | 667 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "15-19", 10)); |
| 658 | 668 |
| 659 histogram = subscriber_->GetHistogramForTesting( | 669 histogram = subscriber_->GetHistogramForTesting( |
| 660 StatsEventSubscriber::QUEUEING_LATENCY_MS_HISTO); | 670 StatsEventSubscriber::QUEUEING_LATENCY_MS_HISTO); |
| 661 ASSERT_TRUE(histogram); | 671 ASSERT_TRUE(histogram); |
| 662 values = histogram->GetHistogram().Pass(); | 672 values = histogram->GetHistogram(); |
| 663 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "100-119", 1)); | 673 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "100-119", 1)); |
| 664 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "200-219", 1)); | 674 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "200-219", 1)); |
| 665 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "300-319", 1)); | 675 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "300-319", 1)); |
| 666 | 676 |
| 667 histogram = subscriber_->GetHistogramForTesting( | 677 histogram = subscriber_->GetHistogramForTesting( |
| 668 StatsEventSubscriber::NETWORK_LATENCY_MS_HISTO); | 678 StatsEventSubscriber::NETWORK_LATENCY_MS_HISTO); |
| 669 ASSERT_TRUE(histogram); | 679 ASSERT_TRUE(histogram); |
| 670 values = histogram->GetHistogram().Pass(); | 680 values = histogram->GetHistogram(); |
| 671 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "100-119", 1)); | 681 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "100-119", 1)); |
| 672 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "200-219", 1)); | 682 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "200-219", 1)); |
| 673 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "300-319", 1)); | 683 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "300-319", 1)); |
| 674 | 684 |
| 675 histogram = subscriber_->GetHistogramForTesting( | 685 histogram = subscriber_->GetHistogramForTesting( |
| 676 StatsEventSubscriber::PACKET_LATENCY_MS_HISTO); | 686 StatsEventSubscriber::PACKET_LATENCY_MS_HISTO); |
| 677 ASSERT_TRUE(histogram); | 687 ASSERT_TRUE(histogram); |
| 678 values = histogram->GetHistogram().Pass(); | 688 values = histogram->GetHistogram(); |
| 679 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "400-419", 3)); | 689 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "400-419", 3)); |
| 680 | 690 |
| 681 histogram = subscriber_->GetHistogramForTesting( | 691 histogram = subscriber_->GetHistogramForTesting( |
| 682 StatsEventSubscriber::LATE_FRAME_MS_HISTO); | 692 StatsEventSubscriber::LATE_FRAME_MS_HISTO); |
| 683 ASSERT_TRUE(histogram); | 693 ASSERT_TRUE(histogram); |
| 684 values = histogram->GetHistogram().Pass(); | 694 values = histogram->GetHistogram(); |
| 685 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "100-119", 1)); | 695 EXPECT_TRUE(CheckHistogramHasValue(values.get(), "100-119", 1)); |
| 686 } | 696 } |
| 687 | 697 |
| 688 } // namespace cast | 698 } // namespace cast |
| 689 } // namespace media | 699 } // namespace media |
| OLD | NEW |