Line data Source code
1 : /*
2 : * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 : *
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
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/common_video/include/incoming_video_stream.h"
12 :
13 : #include "webrtc/base/timeutils.h"
14 : #include "webrtc/common_video/video_render_frames.h"
15 : #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
16 : #include "webrtc/system_wrappers/include/event_wrapper.h"
17 :
18 : namespace webrtc {
19 :
20 0 : IncomingVideoStream::IncomingVideoStream(
21 : int32_t delay_ms,
22 0 : rtc::VideoSinkInterface<VideoFrame>* callback)
23 : : incoming_render_thread_(&IncomingVideoStreamThreadFun,
24 : this,
25 : "IncomingVideoStreamThread"),
26 : deliver_buffer_event_(EventTimerWrapper::Create()),
27 : external_callback_(callback),
28 0 : render_buffers_(new VideoRenderFrames(delay_ms)) {
29 0 : RTC_DCHECK(external_callback_);
30 :
31 0 : render_thread_checker_.DetachFromThread();
32 :
33 0 : deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs);
34 0 : incoming_render_thread_.Start();
35 0 : incoming_render_thread_.SetPriority(rtc::kRealtimePriority);
36 0 : }
37 :
38 0 : IncomingVideoStream::~IncomingVideoStream() {
39 0 : RTC_DCHECK(main_thread_checker_.CalledOnValidThread());
40 :
41 : {
42 0 : rtc::CritScope cs(&buffer_critsect_);
43 0 : render_buffers_.reset();
44 : }
45 :
46 0 : deliver_buffer_event_->Set();
47 0 : incoming_render_thread_.Stop();
48 0 : deliver_buffer_event_->StopTimer();
49 0 : }
50 :
51 0 : void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) {
52 0 : RTC_CHECK_RUNS_SERIALIZED(&decoder_race_checker_);
53 : // Hand over or insert frame.
54 0 : rtc::CritScope csB(&buffer_critsect_);
55 0 : if (render_buffers_->AddFrame(video_frame) == 1) {
56 0 : deliver_buffer_event_->Set();
57 : }
58 0 : }
59 :
60 0 : bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) {
61 0 : return static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess();
62 : }
63 :
64 0 : bool IncomingVideoStream::IncomingVideoStreamProcess() {
65 0 : RTC_DCHECK_RUN_ON(&render_thread_checker_);
66 :
67 0 : if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) {
68 : // Get a new frame to render and the time for the frame after this one.
69 0 : rtc::Optional<VideoFrame> frame_to_render;
70 : uint32_t wait_time;
71 : {
72 0 : rtc::CritScope cs(&buffer_critsect_);
73 0 : if (!render_buffers_.get()) {
74 : // Terminating
75 0 : return false;
76 : }
77 0 : frame_to_render = render_buffers_->FrameToRender();
78 0 : wait_time = render_buffers_->TimeToNextFrameRelease();
79 : }
80 :
81 : // Set timer for next frame to render.
82 0 : if (wait_time > kEventMaxWaitTimeMs) {
83 0 : wait_time = kEventMaxWaitTimeMs;
84 : }
85 :
86 0 : deliver_buffer_event_->StartTimer(false, wait_time);
87 :
88 0 : if (frame_to_render) {
89 0 : external_callback_->OnFrame(*frame_to_render);
90 : }
91 : }
92 0 : return true;
93 : }
94 :
95 : } // namespace webrtc
|