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

Side by Side Diff: webrtc/common_video/incoming_video_stream.cc

Issue 2716473002: Use TaskQueue in IncomingVideoStream (Closed)
Patch Set: rebase and squash Created 3 years, 10 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/common_video/include/incoming_video_stream.h" 11 #include "webrtc/common_video/include/incoming_video_stream.h"
12 12
13 #include <memory>
14
13 #include "webrtc/base/timeutils.h" 15 #include "webrtc/base/timeutils.h"
14 #include "webrtc/common_video/video_render_frames.h" 16 #include "webrtc/common_video/video_render_frames.h"
15 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 17 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
16 #include "webrtc/system_wrappers/include/event_wrapper.h" 18 #include "webrtc/system_wrappers/include/event_wrapper.h"
17 19
18 namespace webrtc { 20 namespace webrtc {
19 namespace { 21
20 const int kEventStartupTimeMs = 10; 22 // Capture by moving (std::move) into a lambda isn't possible in C++11
21 const int kEventMaxWaitTimeMs = 100; 23 // (supported in C++14). This class provides the functionality of what would be
22 } // namespace 24 // something like (inside OnFrame):
25 // VideoFrame frame(video_frame);
26 // incoming_render_queue_.PostTask([this, frame = std::move(frame)](){
27 // if (render_buffers_.AddFrame(std::move(frame)) == 1)
28 // Dequeue();
29 // });
30 class IncomingVideoStream::NewFrameTask : public rtc::QueuedTask {
31 public:
32 NewFrameTask(IncomingVideoStream* stream, VideoFrame frame)
33 : stream_(stream), frame_(std::move(frame)) {}
34
35 private:
36 bool Run() override {
37 if (stream_->render_buffers_.AddFrame(std::move(frame_)) == 1)
mflodman 2017/02/23 15:23:25 There is no check that this happens on the right t
tommi 2017/02/23 19:00:08 Check added. Dequeue would have caught it, but on
mflodman 2017/02/24 15:29:58 If render_buffers_ were empty yes, but not otherwi
38 stream_->Dequeue();
39 return true;
40 }
41
42 IncomingVideoStream* stream_;
43 VideoFrame frame_;
44 };
23 45
24 IncomingVideoStream::IncomingVideoStream( 46 IncomingVideoStream::IncomingVideoStream(
25 int32_t delay_ms, 47 int32_t delay_ms,
26 rtc::VideoSinkInterface<VideoFrame>* callback) 48 rtc::VideoSinkInterface<VideoFrame>* callback)
27 : incoming_render_thread_(&IncomingVideoStreamThreadFun, 49 : render_buffers_(delay_ms),
28 this, 50 callback_(callback),
29 "IncomingVideoStreamThread", 51 incoming_render_queue_("IncomingVideoStream", rtc::TaskQueue::HIGH) {}
30 rtc::kRealtimePriority),
31 deliver_buffer_event_(EventTimerWrapper::Create()),
32 external_callback_(callback),
33 render_buffers_(new VideoRenderFrames(delay_ms)) {
34 RTC_DCHECK(external_callback_);
35
36 render_thread_checker_.DetachFromThread();
37
38 deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs);
39 incoming_render_thread_.Start();
40 }
41 52
42 IncomingVideoStream::~IncomingVideoStream() { 53 IncomingVideoStream::~IncomingVideoStream() {
43 RTC_DCHECK(main_thread_checker_.CalledOnValidThread()); 54 RTC_DCHECK(main_thread_checker_.CalledOnValidThread());
44
45 {
46 rtc::CritScope cs(&buffer_critsect_);
47 render_buffers_.reset();
48 }
49
50 deliver_buffer_event_->Set();
51 incoming_render_thread_.Stop();
52 deliver_buffer_event_->StopTimer();
53 } 55 }
54 56
55 void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) { 57 void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) {
56 RTC_CHECK_RUNS_SERIALIZED(&decoder_race_checker_); 58 RTC_CHECK_RUNS_SERIALIZED(&decoder_race_checker_);
57 // Hand over or insert frame. 59 RTC_DCHECK(!incoming_render_queue_.IsCurrent());
58 rtc::CritScope csB(&buffer_critsect_); 60 incoming_render_queue_.PostTask(
59 if (render_buffers_->AddFrame(video_frame) == 1) { 61 std::unique_ptr<rtc::QueuedTask>(new NewFrameTask(this, video_frame)));
60 deliver_buffer_event_->Set(); 62 }
63
64 void IncomingVideoStream::Dequeue() {
65 RTC_DCHECK(incoming_render_queue_.IsCurrent());
66 rtc::Optional<VideoFrame> frame_to_render = render_buffers_.FrameToRender();
67 if (frame_to_render)
68 callback_->OnFrame(*frame_to_render);
69
70 if (render_buffers_.HasPendingFrames()) {
71 uint32_t wait_time = render_buffers_.TimeToNextFrameRelease();
72 incoming_render_queue_.PostDelayedTask([this]() { Dequeue(); }, wait_time);
mflodman 2017/02/23 15:23:25 'wait_time' can in theory be '0, e.g. if 'OnFrame'
tommi 2017/02/23 19:00:08 That's ok. Also added test for TaskQueue.
mflodman 2017/02/24 15:29:58 Thanks
61 } 73 }
62 } 74 }
63 75
64 // static
65 void IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) {
66 static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess();
67 }
68
69 void IncomingVideoStream::IncomingVideoStreamProcess() {
70 RTC_DCHECK_RUN_ON(&render_thread_checker_);
71
72 while (true) {
73 if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) {
74 // Get a new frame to render and the time for the frame after this one.
75 rtc::Optional<VideoFrame> frame_to_render;
76 uint32_t wait_time;
77 {
78 rtc::CritScope cs(&buffer_critsect_);
79 if (!render_buffers_.get()) {
80 // Terminating
81 return;
82 }
83
84 frame_to_render = render_buffers_->FrameToRender();
85 wait_time = render_buffers_->TimeToNextFrameRelease();
86 }
87
88 // Set timer for next frame to render.
89 if (wait_time > kEventMaxWaitTimeMs) {
90 wait_time = kEventMaxWaitTimeMs;
91 }
92
93 deliver_buffer_event_->StartTimer(false, wait_time);
94
95 if (frame_to_render) {
96 external_callback_->OnFrame(*frame_to_render);
97 }
98 } else {
99 RTC_NOTREACHED();
100 }
101 }
102 }
103
104 } // namespace webrtc 76 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698