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

Side by Side Diff: remoting/test/test_video_renderer.cc

Issue 1214113009: Update TestVideoRenderer with video decoding capabilities (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: "Addressed feedback from Joe: changed the callback mechanism" Created 5 years, 5 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 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/test/test_video_renderer.h" 5 #include "remoting/test/test_video_renderer.h"
6 6
7 #include "base/bind.h"
7 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/synchronization/lock.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/threading/thread.h"
12 #include "remoting/codec/video_decoder.h"
13 #include "remoting/codec/video_decoder_verbatim.h"
14 #include "remoting/codec/video_decoder_vpx.h"
8 #include "remoting/proto/video.pb.h" 15 #include "remoting/proto/video.pb.h"
16 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
17 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
9 18
10 namespace remoting { 19 namespace remoting {
11 namespace test { 20 namespace test {
12 21
13 TestVideoRenderer::TestVideoRenderer() : video_frames_processed_(0) { 22 // Implements video decoding functionality.
23 class TestVideoRenderer::Core {
24 public:
25 Core();
26 ~Core();
27
28 // Initializes the internal structures of the class.
29 void Initialize();
30
31 // Used to decode video packets.
32 void ProcessVideoPacket(scoped_ptr<VideoPacket> packet,
33 const base::Closure& done);
34
35 // Initialize a decoder to decode video packets.
36 void SetDecoderForDecoding(const protocol::ChannelConfig::Codec codec);
joedow 2015/06/30 20:07:11 SetCodec or SetCodecForDecoding
liaoyuke 2015/06/30 21:15:01 Done.
37
38 // Returns a copy of the current buffer.
39 scoped_ptr<webrtc::DesktopFrame> GetBufferForTest() const;
40
41 private:
42 // Used to ensure TestVideoRenderer::Core methods are called on the same
43 // thread.
joedow 2015/06/30 20:07:12 nit: Can you shorten the comment so it fits on one
liaoyuke 2015/06/30 21:15:01 Done.
44 base::ThreadChecker thread_checker_;
45
46 // Used to decode video packets.
47 scoped_ptr<VideoDecoder> decoder_;
48
49 // Updated region of the current desktop frame compared to previous one.
50 webrtc::DesktopRegion updated_region_;
51
52 // Screen size of the remote host.
53 webrtc::DesktopSize screen_size_;
54
55 // Used to post tasks back to main thread.
56 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
57
58 // Used to store decoded video frame.
59 scoped_ptr<webrtc::DesktopFrame> buffer_;
60
61 // Protects access to |buffer_|.
62 mutable base::Lock lock_;
63
64 DISALLOW_COPY_AND_ASSIGN(Core);
65 };
66
67 TestVideoRenderer::Core::Core()
68 : main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
69 thread_checker_.DetachFromThread();
70 }
71
72 TestVideoRenderer::Core::~Core() {
73 DCHECK(thread_checker_.CalledOnValidThread());
74 }
75
76 void TestVideoRenderer::Core::Initialize() {
77 DCHECK(thread_checker_.CalledOnValidThread());
78 }
79
80 void TestVideoRenderer::Core::SetDecoderForDecoding(
81 const protocol::ChannelConfig::Codec codec) {
82 DCHECK(thread_checker_.CalledOnValidThread());
83
84 if (decoder_) {
85 LOG(WARNING) << "Decoder is set more than once";
86 }
87
88 switch (codec) {
89 case protocol::ChannelConfig::CODEC_VP8: {
90 DVLOG(2) << "Test Video Renderer will use VP8 decoder";
91 decoder_ = VideoDecoderVpx::CreateForVP8();
92 break;
93 }
94 case protocol::ChannelConfig::CODEC_VP9: {
95 DVLOG(2) << "Test Video Renderer will use VP9 decoder";
96 decoder_ = VideoDecoderVpx::CreateForVP9();
97 break;
98 }
99 case protocol::ChannelConfig::CODEC_VERBATIM: {
100 DVLOG(2) << "Test Video Renderer will use VERBATIM decoder";
101 decoder_.reset(new VideoDecoderVerbatim());
102 break;
103 }
104 default: {
105 NOTREACHED() << "Unsupported codec: " << codec;
106 }
107 }
108 }
109
110 scoped_ptr<webrtc::DesktopFrame>
111 TestVideoRenderer::Core::GetBufferForTest() const {
112 base::AutoLock auto_lock(lock_);
113 DCHECK(buffer_);
114 return make_scoped_ptr(webrtc::BasicDesktopFrame::CopyOf(*buffer_.get()));
115 }
116
117 void TestVideoRenderer::Core::ProcessVideoPacket(
118 scoped_ptr<VideoPacket> packet, const base::Closure& done) {
119 DCHECK(thread_checker_.CalledOnValidThread());
120 DCHECK(decoder_);
121 DCHECK(packet);
122
123 DVLOG(2) << "TestVideoRenderer::Core::ProcessVideoPacket() Called";
124
125 // Screen size is attached on the first packet as well as when the
126 // host screen is resized.
127 if (packet->format().has_screen_width() &&
128 packet->format().has_screen_height()) {
129 webrtc::DesktopSize source_size(packet->format().screen_width(),
130 packet->format().screen_height());
131 if (!screen_size_.equals(source_size)) {
132 screen_size_ = source_size;
133 decoder_->Initialize(screen_size_);
134 buffer_.reset(new webrtc::BasicDesktopFrame(screen_size_));
135 }
136 }
137
138 // To make life easier, assume that the desktop shape is a single rectangle.
139 packet->clear_use_desktop_shape();
140 if (!decoder_->DecodePacket(*packet.get())) {
141 LOG(ERROR) << "Decoder::DecodePacket() failed.";
142 return;
143 }
144
145 {
146 base::AutoLock auto_lock(lock_);
147
148 // Render the decoded packet and write results to the buffer.
149 // Note that the |updated_region_| maintains the changed regions compared to
150 // previous video frame.
151 decoder_->RenderFrame(screen_size_,
152 webrtc::DesktopRect::MakeWH(screen_size_.width(),
153 screen_size_.height()), buffer_->data(),
154 buffer_->stride(), &updated_region_);
155 }
156
157 main_task_runner_->PostTask(FROM_HERE, done);
158 }
159
160 TestVideoRenderer::TestVideoRenderer()
161 : video_decode_thread_(
162 new base::Thread("TestVideoRendererVideoDecodingThread")),
163 weak_factory_(this) {
164 DCHECK(thread_checker_.CalledOnValidThread());
165
166 core_.reset(new Core());
167 if (!video_decode_thread_->Start()) {
168 LOG(ERROR) << "Cannot start TestVideoRenderer";
169 } else {
170 video_decode_task_runner_ = video_decode_thread_->task_runner();
171 video_decode_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Initialize,
172 base::Unretained(core_.get())));
173 }
14 } 174 }
15 175
16 TestVideoRenderer::~TestVideoRenderer() { 176 TestVideoRenderer::~TestVideoRenderer() {
177 DCHECK(thread_checker_.CalledOnValidThread());
178
179 video_decode_task_runner_->DeleteSoon(FROM_HERE, core_.release());
180
181 // The thread's message loop will run until it runs out of work.
182 video_decode_thread_->Stop();
17 } 183 }
18 184
19 void TestVideoRenderer::OnSessionConfig(const protocol::SessionConfig& config) { 185 void TestVideoRenderer::OnSessionConfig(const protocol::SessionConfig& config) {
186 DCHECK(thread_checker_.CalledOnValidThread());
187
20 DVLOG(2) << "TestVideoRenderer::OnSessionConfig() Called"; 188 DVLOG(2) << "TestVideoRenderer::OnSessionConfig() Called";
189 protocol::ChannelConfig::Codec codec = config.video_config().codec;
190 SetDecoderForDecoding(codec);
21 } 191 }
22 192
23 ChromotingStats* TestVideoRenderer::GetStats() { 193 ChromotingStats* TestVideoRenderer::GetStats() {
194 DCHECK(thread_checker_.CalledOnValidThread());
195
24 DVLOG(2) << "TestVideoRenderer::GetStats() Called"; 196 DVLOG(2) << "TestVideoRenderer::GetStats() Called";
25 return nullptr; 197 return nullptr;
26 } 198 }
27 199
28 protocol::VideoStub* TestVideoRenderer::GetVideoStub() { 200 protocol::VideoStub* TestVideoRenderer::GetVideoStub() {
201 DCHECK(thread_checker_.CalledOnValidThread());
202
29 DVLOG(2) << "TestVideoRenderer::GetVideoStub() Called"; 203 DVLOG(2) << "TestVideoRenderer::GetVideoStub() Called";
30 return this; 204 return this;
31 } 205 }
32 206
33 void TestVideoRenderer::ProcessVideoPacket(scoped_ptr<VideoPacket> video_packet, 207 void TestVideoRenderer::ProcessVideoPacket(scoped_ptr<VideoPacket> video_packet,
34 const base::Closure& done) { 208 const base::Closure& done) {
35 if (!video_packet->data().empty()) { 209 DCHECK(thread_checker_.CalledOnValidThread());
36 // If the video frame was not a keep alive frame (i.e. not empty) then 210 DCHECK(video_decode_task_runner_) << "Failed to start video decode thread";
37 // count it. 211
38 DVLOG(2) << "Video Packet Processed, Total: " << ++video_frames_processed_; 212 if (video_packet->has_data() && video_packet->data().size() != 0) {
213 DVLOG(2) << "process video packet is called!";
214
215 // Post video process task to the video decode thread.
216 base::Closure process_video_task = base::Bind(
217 &TestVideoRenderer::Core::ProcessVideoPacket,
218 base::Unretained(core_.get()), base::Passed(&video_packet), done);
219 video_decode_task_runner_->PostTask(FROM_HERE, process_video_task);
39 } else { 220 } else {
40 // Log at a high verbosity level as we receive empty packets frequently and 221 // Log at a high verbosity level as we receive empty packets frequently and
41 // they can clutter up the debug output if the level is set too low. 222 // they can clutter up the debug output if the level is set too low.
42 DVLOG(3) << "Empty Video Packet received."; 223 DVLOG(3) << "Empty Video Packet received.";
43 } 224 done.Run();
44 225 }
45 done.Run(); 226 }
227
228 void TestVideoRenderer::SetDecoderForDecoding(
229 const protocol::ChannelConfig::Codec codec) {
230 DCHECK(thread_checker_.CalledOnValidThread());
231
232 DVLOG(2) << "TestVideoRenderer::SetDecoder() Called";
233 video_decode_task_runner_->PostTask(
234 FROM_HERE, base::Bind(&Core::SetDecoderForDecoding,
235 base::Unretained(core_.get()),
236 codec));
237 }
238
239 scoped_ptr<webrtc::DesktopFrame> TestVideoRenderer::GetBufferForTest() const {
240 DCHECK(thread_checker_.CalledOnValidThread());
241
242 return core_->GetBufferForTest();
46 } 243 }
47 244
48 } // namespace test 245 } // namespace test
49 } // namespace remoting 246 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698