OLD | NEW |
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 "webrtc/base/timeutils.h" | 13 #include "webrtc/base/timeutils.h" |
14 #include "webrtc/common_video/video_render_frames.h" | 14 #include "webrtc/common_video/video_render_frames.h" |
15 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 15 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
16 #include "webrtc/system_wrappers/include/event_wrapper.h" | 16 #include "webrtc/system_wrappers/include/event_wrapper.h" |
17 | 17 |
18 namespace webrtc { | 18 namespace webrtc { |
| 19 namespace { |
| 20 const int kEventStartupTimeMs = 10; |
| 21 const int kEventMaxWaitTimeMs = 100; |
| 22 } // namespace |
19 | 23 |
20 IncomingVideoStream::IncomingVideoStream( | 24 IncomingVideoStream::IncomingVideoStream( |
21 int32_t delay_ms, | 25 int32_t delay_ms, |
22 rtc::VideoSinkInterface<VideoFrame>* callback) | 26 rtc::VideoSinkInterface<VideoFrame>* callback) |
23 : incoming_render_thread_(&IncomingVideoStreamThreadFun, | 27 : incoming_render_thread_(&IncomingVideoStreamThreadFun, |
24 this, | 28 this, |
25 "IncomingVideoStreamThread"), | 29 "IncomingVideoStreamThread", |
| 30 rtc::kRealtimePriority), |
26 deliver_buffer_event_(EventTimerWrapper::Create()), | 31 deliver_buffer_event_(EventTimerWrapper::Create()), |
27 external_callback_(callback), | 32 external_callback_(callback), |
28 render_buffers_(new VideoRenderFrames(delay_ms)) { | 33 render_buffers_(new VideoRenderFrames(delay_ms)) { |
29 RTC_DCHECK(external_callback_); | 34 RTC_DCHECK(external_callback_); |
30 | 35 |
31 render_thread_checker_.DetachFromThread(); | 36 render_thread_checker_.DetachFromThread(); |
32 | 37 |
33 deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs); | 38 deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs); |
34 incoming_render_thread_.Start(); | 39 incoming_render_thread_.Start(); |
35 incoming_render_thread_.SetPriority(rtc::kRealtimePriority); | |
36 } | 40 } |
37 | 41 |
38 IncomingVideoStream::~IncomingVideoStream() { | 42 IncomingVideoStream::~IncomingVideoStream() { |
39 RTC_DCHECK(main_thread_checker_.CalledOnValidThread()); | 43 RTC_DCHECK(main_thread_checker_.CalledOnValidThread()); |
40 | 44 |
41 { | 45 { |
42 rtc::CritScope cs(&buffer_critsect_); | 46 rtc::CritScope cs(&buffer_critsect_); |
43 render_buffers_.reset(); | 47 render_buffers_.reset(); |
44 } | 48 } |
45 | 49 |
46 deliver_buffer_event_->Set(); | 50 deliver_buffer_event_->Set(); |
47 incoming_render_thread_.Stop(); | 51 incoming_render_thread_.Stop(); |
48 deliver_buffer_event_->StopTimer(); | 52 deliver_buffer_event_->StopTimer(); |
49 } | 53 } |
50 | 54 |
51 void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) { | 55 void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) { |
52 RTC_CHECK_RUNS_SERIALIZED(&decoder_race_checker_); | 56 RTC_CHECK_RUNS_SERIALIZED(&decoder_race_checker_); |
53 // Hand over or insert frame. | 57 // Hand over or insert frame. |
54 rtc::CritScope csB(&buffer_critsect_); | 58 rtc::CritScope csB(&buffer_critsect_); |
55 if (render_buffers_->AddFrame(video_frame) == 1) { | 59 if (render_buffers_->AddFrame(video_frame) == 1) { |
56 deliver_buffer_event_->Set(); | 60 deliver_buffer_event_->Set(); |
57 } | 61 } |
58 } | 62 } |
59 | 63 |
60 bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) { | 64 // static |
61 return static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess(); | 65 void IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) { |
| 66 static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess(); |
62 } | 67 } |
63 | 68 |
64 bool IncomingVideoStream::IncomingVideoStreamProcess() { | 69 void IncomingVideoStream::IncomingVideoStreamProcess() { |
65 RTC_DCHECK_RUN_ON(&render_thread_checker_); | 70 RTC_DCHECK_RUN_ON(&render_thread_checker_); |
66 | 71 |
67 if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) { | 72 while (true) { |
68 // Get a new frame to render and the time for the frame after this one. | 73 if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) { |
69 rtc::Optional<VideoFrame> frame_to_render; | 74 // Get a new frame to render and the time for the frame after this one. |
70 uint32_t wait_time; | 75 rtc::Optional<VideoFrame> frame_to_render; |
71 { | 76 uint32_t wait_time; |
72 rtc::CritScope cs(&buffer_critsect_); | 77 { |
73 if (!render_buffers_.get()) { | 78 rtc::CritScope cs(&buffer_critsect_); |
74 // Terminating | 79 if (!render_buffers_.get()) { |
75 return false; | 80 // Terminating |
| 81 return; |
| 82 } |
| 83 |
| 84 frame_to_render = render_buffers_->FrameToRender(); |
| 85 wait_time = render_buffers_->TimeToNextFrameRelease(); |
76 } | 86 } |
77 frame_to_render = render_buffers_->FrameToRender(); | |
78 wait_time = render_buffers_->TimeToNextFrameRelease(); | |
79 } | |
80 | 87 |
81 // Set timer for next frame to render. | 88 // Set timer for next frame to render. |
82 if (wait_time > kEventMaxWaitTimeMs) { | 89 if (wait_time > kEventMaxWaitTimeMs) { |
83 wait_time = kEventMaxWaitTimeMs; | 90 wait_time = kEventMaxWaitTimeMs; |
84 } | 91 } |
85 | 92 |
86 deliver_buffer_event_->StartTimer(false, wait_time); | 93 deliver_buffer_event_->StartTimer(false, wait_time); |
87 | 94 |
88 if (frame_to_render) { | 95 if (frame_to_render) { |
89 external_callback_->OnFrame(*frame_to_render); | 96 external_callback_->OnFrame(*frame_to_render); |
| 97 } |
| 98 } else { |
| 99 RTC_NOTREACHED(); |
90 } | 100 } |
91 } | 101 } |
92 return true; | |
93 } | 102 } |
94 | 103 |
95 } // namespace webrtc | 104 } // namespace webrtc |
OLD | NEW |