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

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

Issue 2078873002: Reland of Split IncomingVideoStream into two implementations, with smoothing and without. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Remove unused header Created 4 years, 6 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 <assert.h>
14
15 #include "webrtc/base/platform_thread.h"
16 #include "webrtc/base/timeutils.h" 13 #include "webrtc/base/timeutils.h"
17 #include "webrtc/common_video/video_render_frames.h" 14 #include "webrtc/common_video/video_render_frames.h"
18 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 15 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
19 #include "webrtc/system_wrappers/include/event_wrapper.h" 16 #include "webrtc/system_wrappers/include/event_wrapper.h"
20 17
21 namespace webrtc { 18 namespace webrtc {
22 19
23 IncomingVideoStream::IncomingVideoStream(bool disable_prerenderer_smoothing) 20 IncomingVideoStream::IncomingVideoStream(
24 : disable_prerenderer_smoothing_(disable_prerenderer_smoothing), 21 int32_t delay_ms,
25 incoming_render_thread_(), 22 rtc::VideoSinkInterface<VideoFrame>* callback)
23 : incoming_render_thread_(&IncomingVideoStreamThreadFun,
24 this,
25 "IncomingVideoStreamThread"),
26 deliver_buffer_event_(EventTimerWrapper::Create()), 26 deliver_buffer_event_(EventTimerWrapper::Create()),
27 running_(false), 27 external_callback_(callback),
28 external_callback_(nullptr), 28 render_buffers_(new VideoRenderFrames(delay_ms)) {
29 render_buffers_(new VideoRenderFrames()) {} 29 RTC_DCHECK(external_callback_);
30
31 render_thread_checker_.DetachFromThread();
32 decoder_thread_checker_.DetachFromThread();
33
34 incoming_render_thread_.Start();
35 incoming_render_thread_.SetPriority(rtc::kRealtimePriority);
36 deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs);
37 }
30 38
31 IncomingVideoStream::~IncomingVideoStream() { 39 IncomingVideoStream::~IncomingVideoStream() {
32 Stop(); 40 RTC_DCHECK(main_thread_checker_.CalledOnValidThread());
41
42 {
43 rtc::CritScope cs(&buffer_critsect_);
44 render_buffers_.reset();
45 }
46
47 deliver_buffer_event_->Set();
48 incoming_render_thread_.Stop();
49 deliver_buffer_event_->StopTimer();
33 } 50 }
34 51
35 void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) { 52 void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) {
36 rtc::CritScope csS(&stream_critsect_); 53 RTC_DCHECK_RUN_ON(&decoder_thread_checker_);
37
38 if (!running_) {
39 return;
40 }
41 54
42 // Hand over or insert frame. 55 // Hand over or insert frame.
43 if (disable_prerenderer_smoothing_) { 56 rtc::CritScope csB(&buffer_critsect_);
44 DeliverFrame(video_frame); 57 if (render_buffers_->AddFrame(video_frame) == 1) {
45 } else { 58 deliver_buffer_event_->Set();
46 rtc::CritScope csB(&buffer_critsect_);
47 if (render_buffers_->AddFrame(video_frame) == 1) {
48 deliver_buffer_event_->Set();
49 }
50 } 59 }
51 } 60 }
52 61
53 int32_t IncomingVideoStream::SetExpectedRenderDelay(
54 int32_t delay_ms) {
55 rtc::CritScope csS(&stream_critsect_);
56 if (running_) {
57 return -1;
58 }
59 rtc::CritScope cs(&buffer_critsect_);
60 return render_buffers_->SetRenderDelay(delay_ms);
61 }
62
63 void IncomingVideoStream::SetExternalCallback(
64 rtc::VideoSinkInterface<VideoFrame>* external_callback) {
65 rtc::CritScope cs(&thread_critsect_);
66 external_callback_ = external_callback;
67 }
68
69 int32_t IncomingVideoStream::Start() {
70 rtc::CritScope csS(&stream_critsect_);
71 if (running_) {
72 return 0;
73 }
74
75 if (!disable_prerenderer_smoothing_) {
76 rtc::CritScope csT(&thread_critsect_);
77 assert(incoming_render_thread_ == NULL);
78
79 incoming_render_thread_.reset(new rtc::PlatformThread(
80 IncomingVideoStreamThreadFun, this, "IncomingVideoStreamThread"));
81 if (!incoming_render_thread_) {
82 return -1;
83 }
84
85 incoming_render_thread_->Start();
86 incoming_render_thread_->SetPriority(rtc::kRealtimePriority);
87 deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs);
88 }
89
90 running_ = true;
91 return 0;
92 }
93
94 int32_t IncomingVideoStream::Stop() {
95 rtc::CritScope cs_stream(&stream_critsect_);
96
97 if (!running_) {
98 return 0;
99 }
100
101 rtc::PlatformThread* thread = NULL;
102 {
103 rtc::CritScope cs_thread(&thread_critsect_);
104 if (incoming_render_thread_) {
105 // Setting the incoming render thread to NULL marks that we're performing
106 // a shutdown and will make IncomingVideoStreamProcess abort after wakeup.
107 thread = incoming_render_thread_.release();
108 deliver_buffer_event_->StopTimer();
109 // Set the event to allow the thread to wake up and shut down without
110 // waiting for a timeout.
111 deliver_buffer_event_->Set();
112 }
113 }
114 if (thread) {
115 thread->Stop();
116 delete thread;
117 }
118 running_ = false;
119 return 0;
120 }
121
122 bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) { 62 bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) {
123 return static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess(); 63 return static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess();
124 } 64 }
125 65
126 bool IncomingVideoStream::IncomingVideoStreamProcess() { 66 bool IncomingVideoStream::IncomingVideoStreamProcess() {
67 RTC_DCHECK_RUN_ON(&render_thread_checker_);
68
127 if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) { 69 if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) {
128 rtc::CritScope cs(&thread_critsect_);
129 if (incoming_render_thread_ == NULL) {
130 // Terminating
131 return false;
132 }
133
134 // Get a new frame to render and the time for the frame after this one. 70 // Get a new frame to render and the time for the frame after this one.
135 rtc::Optional<VideoFrame> frame_to_render; 71 rtc::Optional<VideoFrame> frame_to_render;
136 uint32_t wait_time; 72 uint32_t wait_time;
137 { 73 {
138 rtc::CritScope cs(&buffer_critsect_); 74 rtc::CritScope cs(&buffer_critsect_);
75 if (!render_buffers_.get()) {
76 // Terminating
77 return false;
78 }
139 frame_to_render = render_buffers_->FrameToRender(); 79 frame_to_render = render_buffers_->FrameToRender();
140 wait_time = render_buffers_->TimeToNextFrameRelease(); 80 wait_time = render_buffers_->TimeToNextFrameRelease();
141 } 81 }
142 82
143 // Set timer for next frame to render. 83 // Set timer for next frame to render.
144 if (wait_time > kEventMaxWaitTimeMs) { 84 if (wait_time > kEventMaxWaitTimeMs) {
145 wait_time = kEventMaxWaitTimeMs; 85 wait_time = kEventMaxWaitTimeMs;
146 } 86 }
87
147 deliver_buffer_event_->StartTimer(false, wait_time); 88 deliver_buffer_event_->StartTimer(false, wait_time);
148 89
149 if (frame_to_render) 90 if (frame_to_render) {
150 DeliverFrame(*frame_to_render); 91 external_callback_->OnFrame(*frame_to_render);
92 }
151 } 93 }
152 return true; 94 return true;
153 } 95 }
154 96
155 void IncomingVideoStream::DeliverFrame(const VideoFrame& video_frame) {
156 rtc::CritScope cs(&thread_critsect_);
157
158 // Send frame for rendering.
159 if (external_callback_) {
160 external_callback_->OnFrame(video_frame);
161 }
162 }
163
164 } // namespace webrtc 97 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/common_video/include/incoming_video_stream.h ('k') | webrtc/common_video/video_render_frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698