Commit 13d9b125 authored by miu's avatar miu Committed by Commit bot

[Cast] Fix shutdown race between CastReceiverImpl/FrameReceiver and frame emit callback run.

As described in bug 396413, it was possible for a posted task to be run
after CastReceiverImpl/FrameReceiver were destroyed.  This change fixes
the bug by having FrameReceiver post a cancelable task (i.e., using its
WeakPtr) instead.

BUG=396413

Review URL: https://codereview.chromium.org/491953003

Cr-Commit-Position: refs/heads/master@{#292244}
parent 56bd38e3
...@@ -256,7 +256,9 @@ void FrameReceiver::EmitAvailableEncodedFrames() { ...@@ -256,7 +256,9 @@ void FrameReceiver::EmitAvailableEncodedFrames() {
} }
cast_environment_->PostTask(CastEnvironment::MAIN, cast_environment_->PostTask(CastEnvironment::MAIN,
FROM_HERE, FROM_HERE,
base::Bind(frame_request_queue_.front(), base::Bind(&FrameReceiver::EmitOneFrame,
weak_factory_.GetWeakPtr(),
frame_request_queue_.front(),
base::Passed(&encoded_frame))); base::Passed(&encoded_frame)));
frame_request_queue_.pop_front(); frame_request_queue_.pop_front();
} }
...@@ -269,6 +271,13 @@ void FrameReceiver::EmitAvailableEncodedFramesAfterWaiting() { ...@@ -269,6 +271,13 @@ void FrameReceiver::EmitAvailableEncodedFramesAfterWaiting() {
EmitAvailableEncodedFrames(); EmitAvailableEncodedFrames();
} }
void FrameReceiver::EmitOneFrame(const ReceiveEncodedFrameCallback& callback,
scoped_ptr<EncodedFrame> encoded_frame) const {
DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
if (!callback.is_null())
callback.Run(encoded_frame.Pass());
}
base::TimeTicks FrameReceiver::GetPlayoutTime(const EncodedFrame& frame) const { base::TimeTicks FrameReceiver::GetPlayoutTime(const EncodedFrame& frame) const {
base::TimeDelta target_playout_delay = target_playout_delay_; base::TimeDelta target_playout_delay = target_playout_delay_;
if (frame.new_playout_delay_ms) { if (frame.new_playout_delay_ms) {
......
...@@ -89,6 +89,13 @@ class FrameReceiver : public RtpPayloadFeedback, ...@@ -89,6 +89,13 @@ class FrameReceiver : public RtpPayloadFeedback,
// EmitAvailableEncodedFrames(). // EmitAvailableEncodedFrames().
void EmitAvailableEncodedFramesAfterWaiting(); void EmitAvailableEncodedFramesAfterWaiting();
// Helper that runs |callback|, passing ownership of |encoded_frame| to it.
// This method is used by EmitAvailableEncodedFrames() to return to the event
// loop, but make sure that FrameReceiver is still alive before the callback
// is run.
void EmitOneFrame(const ReceiveEncodedFrameCallback& callback,
scoped_ptr<EncodedFrame> encoded_frame) const;
// Computes the playout time for a frame with the given |rtp_timestamp|. // Computes the playout time for a frame with the given |rtp_timestamp|.
// Because lip-sync info is refreshed regularly, calling this method with the // Because lip-sync info is refreshed regularly, calling this method with the
// same argument may return different results. // same argument may return different results.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment