Index: webrtc/video/video_receive_stream.cc |
diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc |
index 18cba03e21df11f9cf4e74ca5965729f310a9fb1..74aadc7d095430eadd0c8d1341552ec8e45c30a9 100644 |
--- a/webrtc/video/video_receive_stream.cc |
+++ b/webrtc/video/video_receive_stream.cc |
@@ -32,6 +32,7 @@ |
#include "webrtc/rtc_base/location.h" |
#include "webrtc/rtc_base/logging.h" |
#include "webrtc/rtc_base/optional.h" |
+#include "webrtc/rtc_base/timeutils.h" |
#include "webrtc/rtc_base/trace_event.h" |
#include "webrtc/system_wrappers/include/clock.h" |
#include "webrtc/system_wrappers/include/field_trial.h" |
@@ -306,6 +307,7 @@ void VideoReceiveStream::Start() { |
call_stats_->RegisterStatsObserver(video_stream_decoder_.get()); |
process_thread_->RegisterModule(&video_receiver_, RTC_FROM_HERE); |
+ video_receiver_.DecoderThreadStarting(); |
// Start the decode thread |
decode_thread_.Start(); |
@@ -328,6 +330,7 @@ void VideoReceiveStream::Stop() { |
video_receiver_.TriggerDecoderShutdown(); |
decode_thread_.Stop(); |
+ video_receiver_.DecoderThreadStopped(); |
// Deregister external decoders so they are no longer running during |
// destruction. This effectively stops the VCM since the decoder thread is |
// stopped, the VCM is deregistered and no asynchronous decoder threads are |
@@ -506,10 +509,27 @@ bool VideoReceiveStream::Decode() { |
video_coding::FrameBuffer::ReturnReason res = |
frame_buffer_->NextFrame(wait_ms, &frame); |
- if (res == video_coding::FrameBuffer::ReturnReason::kStopped) { |
- video_receiver_.DecodingStopped(); |
+ video_coding::FrameBuffer::ReturnReason res; |
+#if defined(WEBRTC_ANDROID) |
+ // This is a temporary workaround for video capture on Android in order to |
+ // deliver asynchronously delivered frames, on the decoder thread. |
+ // More details here: |
+ // https://bugs.chromium.org/p/webrtc/issues/detail?id=7361 |
+ static const int kPollIntervalMs = 10; |
+ int time_remaining = kMaxWaitForFrameMs; |
+ do { |
+ res = frame_buffer_->NextFrame(kPollIntervalMs, &frame); |
+ if (res != video_coding::FrameBuffer::ReturnReason::kTimeout) |
+ break; |
+ time_remaining -= kPollIntervalMs; |
+ video_receiver_.PollDecodedFrames(); |
+ } while (time_remaining > 0); |
+#else |
+ res = frame_buffer_->NextFrame(kMaxWaitForFrameMs, &frame); |
+#endif |
+ |
+ if (res == video_coding::FrameBuffer::ReturnReason::kStopped) |
return false; |
- } |
if (frame) { |
RTC_DCHECK_EQ(res, video_coding::FrameBuffer::ReturnReason::kFrameFound); |
@@ -546,6 +566,7 @@ bool VideoReceiveStream::Decode() { |
RequestKeyFrame(); |
} |
} |
+ |
return true; |
} |
} // namespace internal |