From ec02ee4181c49b61fce1c8fb99292dbb8139cc90 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 12 Jul 2017 14:07:37 +0200 Subject: BASELINE: Update Chromium to 59.0.3071.134 Change-Id: Id02ef6fb2204c5fd21668a1c3e6911c83b17585a Reviewed-by: Alexandru Croitor --- chromium/media/cast/BUILD.gn | 3 + chromium/media/cast/sender/congestion_control.cc | 80 ++++++++++----- .../cast/sender/congestion_control_unittest.cc | 47 +++++++++ .../media/cast/sender/h264_vt_encoder_unittest.cc | 7 +- .../cast/sender/performance_metrics_overlay.cc | 110 +++++++++++++-------- .../cast/sender/performance_metrics_overlay.h | 40 ++++---- chromium/media/cast/sender/video_sender.cc | 22 ++--- 7 files changed, 210 insertions(+), 99 deletions(-) (limited to 'chromium/media/cast') diff --git a/chromium/media/cast/BUILD.gn b/chromium/media/cast/BUILD.gn index 43b3db19559..bd5a8484c7a 100644 --- a/chromium/media/cast/BUILD.gn +++ b/chromium/media/cast/BUILD.gn @@ -42,6 +42,7 @@ source_set("common") { "logging/logging_defines.cc", "logging/logging_defines.h", "logging/proto/proto_utils.cc", + "logging/proto/proto_utils.h", "logging/raw_event_subscriber.h", "logging/raw_event_subscriber_bundle.cc", "logging/raw_event_subscriber_bundle.h", @@ -80,6 +81,7 @@ source_set("net") { "net/pacing/paced_sender.cc", "net/pacing/paced_sender.h", "net/rtcp/receiver_rtcp_event_subscriber.cc", + "net/rtcp/receiver_rtcp_event_subscriber.h", "net/rtcp/receiver_rtcp_session.cc", "net/rtcp/receiver_rtcp_session.h", "net/rtcp/rtcp_builder.cc", @@ -310,6 +312,7 @@ test("cast_unittests") { "net/rtp/packet_storage_unittest.cc", "net/rtp/receiver_stats_unittest.cc", "net/rtp/rtp_packet_builder.cc", + "net/rtp/rtp_packet_builder.h", "net/rtp/rtp_packetizer_unittest.cc", "net/rtp/rtp_parser_unittest.cc", "net/udp_transport_unittest.cc", diff --git a/chromium/media/cast/sender/congestion_control.cc b/chromium/media/cast/sender/congestion_control.cc index c7d81ad3659..7cdbb5d98f8 100644 --- a/chromium/media/cast/sender/congestion_control.cc +++ b/chromium/media/cast/sender/congestion_control.cc @@ -60,7 +60,10 @@ class AdaptiveCongestionControl : public CongestionControl { // Calculate how much "dead air" (idle time) there is between two frames. static base::TimeDelta DeadTime(const FrameStats& a, const FrameStats& b); - // Get the FrameStats for a given |frame_id|. Never returns nullptr. + // Get the FrameStats for a given |frame_id|, auto-creating a new FrameStats + // for newer frames, but possibly returning nullptr for older frames that have + // been pruned. Never returns nullptr for |frame_id|s equal to or greater than + // |last_checkpoint_frame_|. // Note: Older FrameStats will be removed automatically. FrameStats* GetFrameStats(FrameId frame_id); // Discard old FrameStats. @@ -202,7 +205,8 @@ base::TimeDelta AdaptiveCongestionControl::DeadTime(const FrameStats& a, } double AdaptiveCongestionControl::CalculateSafeBitrate() { - double transmit_time = + DCHECK(!frame_stats_.empty()); + const double transmit_time = (GetFrameStats(last_checkpoint_frame_)->ack_time - frame_stats_.front().enqueue_time - dead_time_in_history_) .InSecondsF(); @@ -215,24 +219,41 @@ double AdaptiveCongestionControl::CalculateSafeBitrate() { AdaptiveCongestionControl::FrameStats* AdaptiveCongestionControl::GetFrameStats( FrameId frame_id) { - DCHECK_LT(frame_id - last_frame_stats_, static_cast(kHistorySize)); int offset = frame_id - last_frame_stats_; if (offset > 0) { + // Sanity-check: Make sure the new |frame_id| will not cause an unreasonably + // large increase in the history dataset. + DCHECK_LE(offset, kMaxUnackedFrames + 1); + frame_stats_.resize(frame_stats_.size() + offset); - last_frame_stats_ += offset; + last_frame_stats_ = frame_id; offset = 0; } PruneFrameStats(); offset += frame_stats_.size() - 1; - // TODO(miu): Change the following to DCHECK once crash fix is confirmed. - // http://crbug.com/517145 - CHECK(offset >= 0 && offset < static_cast(frame_stats_.size())); + if (offset < 0) { + DCHECK_LT(frame_id, last_checkpoint_frame_); + return nullptr; // Old frame has been pruned from the dataset. + } return &frame_stats_[offset]; } void AdaptiveCongestionControl::PruneFrameStats() { - while (frame_stats_.size() > history_size_) { - DCHECK_GT(frame_stats_.size(), 1UL); + // Maintain a minimal amount of history, specified by |history_size_|, that + // MUST also include all frames from the last ACK'ed frame. + const size_t retention_count = std::max( + history_size_, last_frame_stats_ - last_checkpoint_frame_ + 1); + + // Sanity-check: At least one entry must be kept, but the dataset should not + // grow indefinitely. + DCHECK_GE(retention_count, 1u); + constexpr size_t kMaxInFlightRangeSize = + kMaxUnackedFrames + // Maximum unACKed frames. + 1 + // The last ACKed frame. + 1; // One not-yet-enqueued frame (see call to EstimatedSendingTime()). + DCHECK_LE(retention_count, std::max(history_size_, kMaxInFlightRangeSize)); + + while (frame_stats_.size() > retention_count) { DCHECK(!frame_stats_[0].ack_time.is_null()); acked_bits_in_history_ -= frame_stats_[0].frame_size_in_bits; dead_time_in_history_ -= DeadTime(frame_stats_[0], frame_stats_[1]); @@ -249,12 +270,14 @@ void AdaptiveCongestionControl::AckFrame(FrameId frame_id, while (last_checkpoint_frame_ < frame_id) { FrameStats* last_frame_stats = frame_stats; frame_stats = GetFrameStats(last_checkpoint_frame_ + 1); - if (frame_stats->enqueue_time.is_null()) { - // Can't ack a frame that hasn't been sent yet. - return; - } + // Note: This increment must happen AFTER the GetFrameStats() call to + // prevent the |last_frame_stats| pointer from being invalidated. last_checkpoint_frame_++; - if (when < frame_stats->enqueue_time) + // When ACKing a frame that was never sent, just pretend it was sent and + // ACKed at the same point-in-time. + if (frame_stats->enqueue_time.is_null()) + frame_stats->enqueue_time = when; + else if (when < frame_stats->enqueue_time) when = frame_stats->enqueue_time; // Don't overwrite the ack time for those frames that were already acked in // previous extended ACKs. @@ -270,20 +293,21 @@ void AdaptiveCongestionControl::AckFrame(FrameId frame_id, void AdaptiveCongestionControl::AckLaterFrames( std::vector received_frames, base::TimeTicks when) { + DCHECK(std::is_sorted(received_frames.begin(), received_frames.end())); for (FrameId frame_id : received_frames) { - if (last_checkpoint_frame_ < frame_id) { - FrameStats* frame_stats = GetFrameStats(frame_id); - if (frame_stats->enqueue_time.is_null()) { - // Can't ack a frame that hasn't been sent yet. - continue; - } - if (when < frame_stats->enqueue_time) - when = frame_stats->enqueue_time; - // Don't overwrite the ack time for those frames that were acked before. - if (frame_stats->ack_time.is_null()) - frame_stats->ack_time = when; - DCHECK_GE(when, frame_stats->ack_time); - } + if (frame_id <= last_checkpoint_frame_) + continue; + FrameStats* frame_stats = GetFrameStats(frame_id); + // When ACKing a frame that was never sent, just pretend it was sent and + // ACKed at the same point-in-time. + if (frame_stats->enqueue_time.is_null()) + frame_stats->enqueue_time = when; + else if (when < frame_stats->enqueue_time) + when = frame_stats->enqueue_time; + // Don't overwrite the ack time for those frames that were acked before. + if (frame_stats->ack_time.is_null()) + frame_stats->ack_time = when; + DCHECK_GE(when, frame_stats->ack_time); } } @@ -292,6 +316,7 @@ void AdaptiveCongestionControl::SendFrameToTransport(FrameId frame_id, base::TimeTicks when) { last_enqueued_frame_ = frame_id; FrameStats* frame_stats = GetFrameStats(frame_id); + DCHECK(frame_stats); frame_stats->enqueue_time = when; frame_stats->frame_size_in_bits = frame_size_in_bits; } @@ -357,6 +382,7 @@ base::TimeTicks AdaptiveCongestionControl::EstimatedSendingTime( } FrameStats* const frame_stats = GetFrameStats(frame_id); + DCHECK(frame_stats); if (frame_stats->enqueue_time.is_null()) { // The frame has not yet been enqueued for transport. Since it cannot be // enqueued in the past, ensure the result is lower-bounded by |now|. diff --git a/chromium/media/cast/sender/congestion_control_unittest.cc b/chromium/media/cast/sender/congestion_control_unittest.cc index b3884137ed6..561ce87bb2e 100644 --- a/chromium/media/cast/sender/congestion_control_unittest.cc +++ b/chromium/media/cast/sender/congestion_control_unittest.cc @@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/test/simple_test_tick_clock.h" #include "media/base/fake_single_thread_task_runner.h" +#include "media/cast/constants.h" #include "media/cast/sender/congestion_control.h" #include "testing/gtest/include/gtest/gtest.h" @@ -143,5 +144,51 @@ TEST_F(CongestionControlTest, SimpleRun) { safe_bitrate * 0.05); } +// Regression test for http://crbug.com/685392: This confirms that enough +// history is maintained in AdaptiveCongestionControl to avoid invalid +// indexing offsets. This test is successful if it does not crash the process. +TEST_F(CongestionControlTest, RetainsSufficientHistory) { + constexpr base::TimeDelta kFakePlayoutDelay = + base::TimeDelta::FromMilliseconds(400); + + // Sanity-check: With no data, GetBitrate() returns an in-range value. + const int bitrate = congestion_control_->GetBitrate( + testing_clock_.NowTicks() + kFakePlayoutDelay, kFakePlayoutDelay); + ASSERT_GE(bitrate, kMinBitrateConfigured); + ASSERT_LE(bitrate, kMaxBitrateConfigured); + + // Notify AdaptiveCongestionControl of a large number (the maximum possible) + // of frames being enqueued for transport, but not yet ACKed. Confirm + // GetBitrate() returns an in-range value at each step. + FrameId frame_id = FrameId::first(); + for (int i = 0; i < kMaxUnackedFrames; ++i) { + congestion_control_->SendFrameToTransport(frame_id, 16384, + testing_clock_.NowTicks()); + + const int bitrate = congestion_control_->GetBitrate( + testing_clock_.NowTicks() + kFakePlayoutDelay, kFakePlayoutDelay); + ASSERT_GE(bitrate, kMinBitrateConfigured); + ASSERT_LE(bitrate, kMaxBitrateConfigured); + + task_runner_->Sleep(base::TimeDelta::FromMilliseconds(kFrameDelayMs)); + ++frame_id; + } + + // Notify AdaptiveCongestionControl that each frame is ACK'ed, again checking + // that GetBitrate() returns an in-range value at each step. + frame_id = FrameId::first(); + for (int i = 0; i < kMaxUnackedFrames; ++i) { + congestion_control_->AckFrame(frame_id, testing_clock_.NowTicks()); + + const int bitrate = congestion_control_->GetBitrate( + testing_clock_.NowTicks() + kFakePlayoutDelay, kFakePlayoutDelay); + ASSERT_GE(bitrate, kMinBitrateConfigured); + ASSERT_LE(bitrate, kMaxBitrateConfigured); + + task_runner_->Sleep(base::TimeDelta::FromMilliseconds(kFrameDelayMs)); + ++frame_id; + } +} + } // namespace cast } // namespace media diff --git a/chromium/media/cast/sender/h264_vt_encoder_unittest.cc b/chromium/media/cast/sender/h264_vt_encoder_unittest.cc index 72ff6735224..8fdf50ab900 100644 --- a/chromium/media/cast/sender/h264_vt_encoder_unittest.cc +++ b/chromium/media/cast/sender/h264_vt_encoder_unittest.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/macros.h" +#include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" #include "base/power_monitor/power_monitor.h" #include "base/run_loop.h" @@ -19,6 +20,7 @@ #include "media/base/cdm_context.h" #include "media/base/decoder_buffer.h" #include "media/base/media.h" +#include "media/base/media_log.h" #include "media/base/media_switches.h" #include "media/base/media_util.h" #include "media/cast/common/rtp_time.h" @@ -128,7 +130,8 @@ class EndToEndFrameChecker : public base::RefCountedThreadSafe { public: explicit EndToEndFrameChecker(const VideoDecoderConfig& config) - : decoder_(), count_frames_checked_(0) { + : decoder_(make_scoped_refptr(new media::MediaLog())), + count_frames_checked_(0) { bool decoder_init_result; decoder_.Initialize( config, false, nullptr, @@ -178,7 +181,7 @@ void CreateFrameAndMemsetPlane(VideoFrameFactory* const video_frame_factory) { video_frame_factory->MaybeCreateFrame( gfx::Size(kVideoWidth, kVideoHeight), base::TimeDelta()); ASSERT_TRUE(video_frame.get()); - auto* cv_pixel_buffer = video_frame->cv_pixel_buffer(); + auto* cv_pixel_buffer = video_frame->CvPixelBuffer(); ASSERT_TRUE(cv_pixel_buffer); CVPixelBufferLockBaseAddress(cv_pixel_buffer, 0); auto* ptr = CVPixelBufferGetBaseAddressOfPlane(cv_pixel_buffer, 0); diff --git a/chromium/media/cast/sender/performance_metrics_overlay.cc b/chromium/media/cast/sender/performance_metrics_overlay.cc index 389b6f37cd8..d132db059db 100644 --- a/chromium/media/cast/sender/performance_metrics_overlay.cc +++ b/chromium/media/cast/sender/performance_metrics_overlay.cc @@ -10,6 +10,7 @@ #include #include +#include "base/bind.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/strings/stringprintf.h" @@ -20,12 +21,12 @@ namespace cast { namespace { -const int kScale = 4; // Physical pixels per one logical pixel. -const int kCharacterWidth = 3; // Logical pixel width of one character. -const int kCharacterHeight = 5; // Logical pixel height of one character. -const int kCharacterSpacing = 1; // Logical pixels between each character. -const int kLineSpacing = 2; // Logical pixels between each line of characters. -const int kPlane = 0; // Y-plane in YUV formats. +constexpr int kScale = 4; // Physical pixels per one logical pixel. +constexpr int kCharacterWidth = 3; // Logical pixel width of one character. +constexpr int kCharacterHeight = 5; // Logical pixel height of one character. +constexpr int kCharacterSpacing = 1; // Logical pixels between each character. +constexpr int kLineSpacing = 2; // Logical pixels between each line of chars. +constexpr int kPlane = 0; // Y-plane in YUV formats. // For each pixel in the |rect| (logical coordinates), either decrease the // intensity or increase it so that the resulting pixel has a perceivably @@ -214,29 +215,60 @@ void RenderLineOfText(const std::string& line, int top, VideoFrame* frame) { } // namespace -void MaybeRenderPerformanceMetricsOverlay(base::TimeDelta target_playout_delay, - bool in_low_latency_mode, - int target_bitrate, - int frames_ago, - double encoder_utilization, - double lossy_utilization, - VideoFrame* frame) { - if (VideoFrame::PlaneHorizontalBitsPerPixel(frame->format(), kPlane) != 8) { +scoped_refptr MaybeRenderPerformanceMetricsOverlay( + base::TimeDelta target_playout_delay, + bool in_low_latency_mode, + int target_bitrate, + int frames_ago, + double encoder_utilization, + double lossy_utilization, + scoped_refptr source) { + if (!VLOG_IS_ON(1)) + return source; + + if (VideoFrame::PlaneHorizontalBitsPerPixel(source->format(), kPlane) != 8) { DLOG(WARNING) << "Cannot render overlay: Plane " << kPlane << " not 8bpp."; - return; + return source; } - // Can't render to unmappable memory (DmaBuf, CVPixelBuffer). - if (!frame->IsMappable()) { + // Can't read from unmappable memory (DmaBuf, CVPixelBuffer). + if (!source->IsMappable()) { DVLOG(2) << "Cannot render overlay: frame uses unmappable memory."; - return; + return source; } // Compute the physical pixel top row for the bottom-most line of text. const int line_height = (kCharacterHeight + kLineSpacing) * kScale; - int top = frame->visible_rect().height() - line_height; - if (top < 0 || !VLOG_IS_ON(1)) - return; + int top = source->visible_rect().height() - line_height; + if (top < 0) + return source; // No pixels would change: Return source frame. + + // Allocate a new frame, identical in configuration to |source| and copy over + // all data and metadata. + const scoped_refptr frame = VideoFrame::CreateFrame( + source->format(), source->coded_size(), source->visible_rect(), + source->natural_size(), source->timestamp()); + if (!frame) + return source; // Allocation failure: Return source frame. + for (size_t plane = 0, num_planes = VideoFrame::NumPlanes(source->format()); + plane < num_planes; ++plane) { + memcpy(frame->data(plane), source->data(plane), + source->stride(plane) * source->rows(plane)); + } + frame->metadata()->MergeMetadataFrom(source->metadata()); + // Important: After all consumers are done with the frame, copy-back the + // changed/new metadata to the source frame, as it contains feedback signals + // that need to propagate back up the video stack. The destruction callback + // for the |frame| holds a ref-counted reference to the source frame to ensure + // the source frame has the right metadata before its destruction observers + // are invoked. + frame->AddDestructionObserver(base::Bind( + [](const VideoFrameMetadata* sent_frame_metadata, + const scoped_refptr& source_frame) { + source_frame->metadata()->Clear(); + source_frame->metadata()->MergeMetadataFrom(sent_frame_metadata); + }, + frame->metadata(), std::move(source))); // Line 3: Frame duration, resolution, and timestamp. int frame_duration_ms = 0; @@ -255,21 +287,17 @@ void MaybeRenderPerformanceMetricsOverlay(base::TimeDelta target_playout_delay, const int seconds = static_cast(rem.InSeconds()); rem -= base::TimeDelta::FromSeconds(seconds); const int hundredth_seconds = static_cast(rem.InMilliseconds() / 10); - RenderLineOfText(base::StringPrintf("%d.%01d %dx%d %d:%02d.%02d", - frame_duration_ms, - frame_duration_ms_frac, - frame->visible_rect().width(), - frame->visible_rect().height(), - minutes, - seconds, - hundredth_seconds), - top, - frame); + RenderLineOfText( + base::StringPrintf("%d.%01d %dx%d %d:%02d.%02d", frame_duration_ms, + frame_duration_ms_frac, frame->visible_rect().width(), + frame->visible_rect().height(), minutes, seconds, + hundredth_seconds), + top, frame.get()); // Move up one line's worth of pixels. top -= line_height; if (top < 0 || !VLOG_IS_ON(2)) - return; + return frame; // Line 2: Capture duration, target playout delay, low-latency mode, and // target bitrate. @@ -285,18 +313,16 @@ void MaybeRenderPerformanceMetricsOverlay(base::TimeDelta target_playout_delay, const int target_playout_delay_ms = static_cast(target_playout_delay.InMillisecondsF() + 0.5); const int target_kbits = target_bitrate / 1000; - RenderLineOfText(base::StringPrintf("%d %4.1d%c %4.1d", - capture_duration_ms, - target_playout_delay_ms, - in_low_latency_mode ? '!' : '.', - target_kbits), - top, - frame); + RenderLineOfText( + base::StringPrintf("%d %4.1d%c %4.1d", capture_duration_ms, + target_playout_delay_ms, + in_low_latency_mode ? '!' : '.', target_kbits), + top, frame.get()); // Move up one line's worth of pixels. top -= line_height; if (top < 0 || !VLOG_IS_ON(3)) - return; + return frame; // Line 1: Recent utilization metrics. const int encoder_pct = @@ -305,7 +331,9 @@ void MaybeRenderPerformanceMetricsOverlay(base::TimeDelta target_playout_delay, base::saturated_cast(lossy_utilization * 100.0 + 0.5); RenderLineOfText(base::StringPrintf("%d %3.1d%% %3.1d%%", frames_ago, encoder_pct, lossy_pct), - top, frame); + top, frame.get()); + + return frame; } } // namespace cast diff --git a/chromium/media/cast/sender/performance_metrics_overlay.h b/chromium/media/cast/sender/performance_metrics_overlay.h index e9a66524b8b..774effe19da 100644 --- a/chromium/media/cast/sender/performance_metrics_overlay.h +++ b/chromium/media/cast/sender/performance_metrics_overlay.h @@ -6,6 +6,7 @@ #define MEDIA_CAST_SENDER_PERFORMANCE_METRICS_OVERLAY_H_ #include "base/time/time.h" +#include "media/base/video_frame.h" // This module provides a display of frame-level performance metrics, rendered // in the lower-right corner of a VideoFrame. It looks like this: @@ -48,25 +49,30 @@ // media timestamp in minutes:seconds.hundredths format. namespace media { - -class VideoFrame; - namespace cast { -// Renders an overlay of frame-level performance metrics in the lower-right -// corner of the |frame|, as described above. The verbose logging level for -// video_frame_overlay.cc determines which lines, if any, are rendered: VLOG -// level 1 renders the bottom line only, level 2 renders the bottom and middle -// lines, and level 3 renders all three lines. So, use the -// --vmodule=performance_metrics_overlay=3 command line argument to turn on -// rendering of the entire overlay. -void MaybeRenderPerformanceMetricsOverlay(base::TimeDelta target_playout_delay, - bool in_low_latency_mode, - int target_bitrate, - int frames_ago, - double encoder_utilization, - double lossy_utilization, - VideoFrame* frame); +// If the user has requested VideoFrames have a performance metrics overlay +// rendered on them, this function copies the |source| frame and then renders an +// overlay on the copy. Frame-level performance metrics will be rendered in the +// lower-right corner of the frame, as described in the module-level comments +// above. +// +// The verbose logging level for video_frame_overlay.cc determines which lines, +// if any, are rendered: no VLOG level does nothing, level 1 renders the bottom +// line only, level 2 renders the bottom and middle lines, and level 3 renders +// all three lines. So, use the --vmodule=performance_metrics_overlay=3 command +// line argument to turn on rendering of the entire overlay. +// +// Note: If |source| is an unsupported format, or no pixels need to be modified, +// this function will just return |source|. +scoped_refptr MaybeRenderPerformanceMetricsOverlay( + base::TimeDelta target_playout_delay, + bool in_low_latency_mode, + int target_bitrate, + int frames_ago, + double encoder_utilization, + double lossy_utilization, + scoped_refptr source); } // namespace cast } // namespace media diff --git a/chromium/media/cast/sender/video_sender.cc b/chromium/media/cast/sender/video_sender.cc index a0c15e02f54..8447223d1e9 100644 --- a/chromium/media/cast/sender/video_sender.cc +++ b/chromium/media/cast/sender/video_sender.cc @@ -250,20 +250,18 @@ void VideoSender::InsertRawVideoFrame( TRACE_COUNTER_ID1("cast.stream", "Video Target Bitrate", this, bitrate); - MaybeRenderPerformanceMetricsOverlay( - GetTargetPlayoutDelay(), low_latency_mode_, bitrate, - frames_in_encoder_ + 1, last_reported_encoder_utilization_, - last_reported_lossy_utilization_, video_frame.get()); - + const scoped_refptr frame_to_encode = + MaybeRenderPerformanceMetricsOverlay( + GetTargetPlayoutDelay(), low_latency_mode_, bitrate, + frames_in_encoder_ + 1, last_reported_encoder_utilization_, + last_reported_lossy_utilization_, video_frame); if (video_encoder_->EncodeVideoFrame( - video_frame, - reference_time, + frame_to_encode, reference_time, base::Bind(&VideoSender::OnEncodedVideoFrame, - weak_factory_.GetWeakPtr(), - video_frame, - bitrate))) { - TRACE_EVENT_ASYNC_BEGIN1("cast.stream", "Video Encode", video_frame.get(), - "rtp_timestamp", rtp_timestamp.lower_32_bits()); + weak_factory_.GetWeakPtr(), frame_to_encode, bitrate))) { + TRACE_EVENT_ASYNC_BEGIN1("cast.stream", "Video Encode", + frame_to_encode.get(), "rtp_timestamp", + rtp_timestamp.lower_32_bits()); frames_in_encoder_++; duration_in_encoder_ += duration_added_by_next_frame; last_enqueued_frame_rtp_timestamp_ = rtp_timestamp; -- cgit v1.2.1