| OLD | NEW |
| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/memory/ptr_util.h" |
| 13 #include "base/synchronization/lock.h" | 14 #include "base/synchronization/lock.h" |
| 14 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
| 15 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 16 #include "remoting/codec/video_decoder.h" | 17 #include "remoting/codec/video_decoder.h" |
| 17 #include "remoting/codec/video_decoder_verbatim.h" | 18 #include "remoting/codec/video_decoder_verbatim.h" |
| 18 #include "remoting/codec/video_decoder_vpx.h" | 19 #include "remoting/codec/video_decoder_vpx.h" |
| 19 #include "remoting/proto/video.pb.h" | 20 #include "remoting/proto/video.pb.h" |
| 20 #include "remoting/test/rgb_value.h" | 21 #include "remoting/test/rgb_value.h" |
| 21 #include "remoting/test/video_frame_writer.h" | 22 #include "remoting/test/video_frame_writer.h" |
| 22 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 23 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 37 // Implements video decoding functionality. | 38 // Implements video decoding functionality. |
| 38 class TestVideoRenderer::Core { | 39 class TestVideoRenderer::Core { |
| 39 public: | 40 public: |
| 40 Core(); | 41 Core(); |
| 41 ~Core(); | 42 ~Core(); |
| 42 | 43 |
| 43 // Initializes the internal structures of the class. | 44 // Initializes the internal structures of the class. |
| 44 void Initialize(); | 45 void Initialize(); |
| 45 | 46 |
| 46 // Used to decode video packets. | 47 // Used to decode video packets. |
| 47 void ProcessVideoPacket(scoped_ptr<VideoPacket> packet, | 48 void ProcessVideoPacket(std::unique_ptr<VideoPacket> packet, |
| 48 const base::Closure& done); | 49 const base::Closure& done); |
| 49 | 50 |
| 50 // Initialize a decoder to decode video packets. | 51 // Initialize a decoder to decode video packets. |
| 51 void SetCodecForDecoding(const protocol::ChannelConfig::Codec codec); | 52 void SetCodecForDecoding(const protocol::ChannelConfig::Codec codec); |
| 52 | 53 |
| 53 // Returns a copy of the current frame. | 54 // Returns a copy of the current frame. |
| 54 scoped_ptr<webrtc::DesktopFrame> GetCurrentFrameForTest() const; | 55 std::unique_ptr<webrtc::DesktopFrame> GetCurrentFrameForTest() const; |
| 55 | 56 |
| 56 // Set expected image pattern for comparison and the callback will be called | 57 // Set expected image pattern for comparison and the callback will be called |
| 57 // when the pattern is matched. | 58 // when the pattern is matched. |
| 58 void ExpectAverageColorInRect( | 59 void ExpectAverageColorInRect( |
| 59 const webrtc::DesktopRect& expected_rect, | 60 const webrtc::DesktopRect& expected_rect, |
| 60 const RGBValue& expected_avg_color, | 61 const RGBValue& expected_avg_color, |
| 61 const base::Closure& image_pattern_matched_callback); | 62 const base::Closure& image_pattern_matched_callback); |
| 62 | 63 |
| 63 // Turn on/off saving video frames to disk. | 64 // Turn on/off saving video frames to disk. |
| 64 void save_frame_data_to_disk(bool save_frame_data_to_disk) { | 65 void save_frame_data_to_disk(bool save_frame_data_to_disk) { |
| 65 save_frame_data_to_disk_ = save_frame_data_to_disk; | 66 save_frame_data_to_disk_ = save_frame_data_to_disk; |
| 66 } | 67 } |
| 67 | 68 |
| 68 private: | 69 private: |
| 69 // Returns average color of pixels fall within |rect| on the current frame. | 70 // Returns average color of pixels fall within |rect| on the current frame. |
| 70 RGBValue CalculateAverageColorValue(const webrtc::DesktopRect& rect) const; | 71 RGBValue CalculateAverageColorValue(const webrtc::DesktopRect& rect) const; |
| 71 | 72 |
| 72 // Compares |candidate_avg_value| to |expected_avg_color_|. | 73 // Compares |candidate_avg_value| to |expected_avg_color_|. |
| 73 // Returns true if the root mean square of the errors in the R, G and B | 74 // Returns true if the root mean square of the errors in the R, G and B |
| 74 // components does not exceed a given limit. | 75 // components does not exceed a given limit. |
| 75 bool ExpectedAverageColorIsMatched(const RGBValue& candidate_avg_value) const; | 76 bool ExpectedAverageColorIsMatched(const RGBValue& candidate_avg_value) const; |
| 76 | 77 |
| 77 // Used to ensure Core methods are called on the same thread. | 78 // Used to ensure Core methods are called on the same thread. |
| 78 base::ThreadChecker thread_checker_; | 79 base::ThreadChecker thread_checker_; |
| 79 | 80 |
| 80 // Used to decode video packets. | 81 // Used to decode video packets. |
| 81 scoped_ptr<VideoDecoder> decoder_; | 82 std::unique_ptr<VideoDecoder> decoder_; |
| 82 | 83 |
| 83 // Used to post tasks back to main thread. | 84 // Used to post tasks back to main thread. |
| 84 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | 85 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
| 85 | 86 |
| 86 // Protects access to |frame_|. | 87 // Protects access to |frame_|. |
| 87 mutable base::Lock lock_; | 88 mutable base::Lock lock_; |
| 88 | 89 |
| 89 // Used to store decoded video frame. | 90 // Used to store decoded video frame. |
| 90 scoped_ptr<webrtc::SharedDesktopFrame> frame_; | 91 std::unique_ptr<webrtc::SharedDesktopFrame> frame_; |
| 91 | 92 |
| 92 // Used to store the expected image pattern. | 93 // Used to store the expected image pattern. |
| 93 webrtc::DesktopRect expected_rect_; | 94 webrtc::DesktopRect expected_rect_; |
| 94 RGBValue expected_avg_color_; | 95 RGBValue expected_avg_color_; |
| 95 | 96 |
| 96 // Used to store the callback when expected pattern is matched. | 97 // Used to store the callback when expected pattern is matched. |
| 97 base::Closure image_pattern_matched_callback_; | 98 base::Closure image_pattern_matched_callback_; |
| 98 | 99 |
| 99 // Used to identify whether saving frame frame data to disk. | 100 // Used to identify whether saving frame frame data to disk. |
| 100 bool save_frame_data_to_disk_; | 101 bool save_frame_data_to_disk_; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 VLOG(1) << "Test Video Renderer will use VERBATIM decoder"; | 143 VLOG(1) << "Test Video Renderer will use VERBATIM decoder"; |
| 143 decoder_.reset(new VideoDecoderVerbatim()); | 144 decoder_.reset(new VideoDecoderVerbatim()); |
| 144 break; | 145 break; |
| 145 } | 146 } |
| 146 default: { | 147 default: { |
| 147 NOTREACHED() << "Unsupported codec: " << codec; | 148 NOTREACHED() << "Unsupported codec: " << codec; |
| 148 } | 149 } |
| 149 } | 150 } |
| 150 } | 151 } |
| 151 | 152 |
| 152 scoped_ptr<webrtc::DesktopFrame> | 153 std::unique_ptr<webrtc::DesktopFrame> |
| 153 TestVideoRenderer::Core::GetCurrentFrameForTest() const { | 154 TestVideoRenderer::Core::GetCurrentFrameForTest() const { |
| 154 base::AutoLock auto_lock(lock_); | 155 base::AutoLock auto_lock(lock_); |
| 155 DCHECK(frame_); | 156 DCHECK(frame_); |
| 156 return make_scoped_ptr(webrtc::BasicDesktopFrame::CopyOf(*frame_)); | 157 return base::WrapUnique(webrtc::BasicDesktopFrame::CopyOf(*frame_)); |
| 157 } | 158 } |
| 158 | 159 |
| 159 void TestVideoRenderer::Core::ProcessVideoPacket(scoped_ptr<VideoPacket> packet, | 160 void TestVideoRenderer::Core::ProcessVideoPacket( |
| 160 const base::Closure& done) { | 161 std::unique_ptr<VideoPacket> packet, |
| 162 const base::Closure& done) { |
| 161 DCHECK(thread_checker_.CalledOnValidThread()); | 163 DCHECK(thread_checker_.CalledOnValidThread()); |
| 162 DCHECK(decoder_); | 164 DCHECK(decoder_); |
| 163 DCHECK(packet); | 165 DCHECK(packet); |
| 164 | 166 |
| 165 VLOG(2) << "TestVideoRenderer::Core::ProcessVideoPacket() Called"; | 167 VLOG(2) << "TestVideoRenderer::Core::ProcessVideoPacket() Called"; |
| 166 | 168 |
| 167 // Screen size is attached on the first packet as well as when the | 169 // Screen size is attached on the first packet as well as when the |
| 168 // host screen is resized. | 170 // host screen is resized. |
| 169 if (packet->format().has_screen_width() && | 171 if (packet->format().has_screen_width() && |
| 170 packet->format().has_screen_height()) { | 172 packet->format().has_screen_height()) { |
| 171 webrtc::DesktopSize source_size(packet->format().screen_width(), | 173 webrtc::DesktopSize source_size(packet->format().screen_width(), |
| 172 packet->format().screen_height()); | 174 packet->format().screen_height()); |
| 173 if (!frame_ || !frame_->size().equals(source_size)) { | 175 if (!frame_ || !frame_->size().equals(source_size)) { |
| 174 base::AutoLock auto_lock(lock_); | 176 base::AutoLock auto_lock(lock_); |
| 175 frame_.reset(webrtc::SharedDesktopFrame::Wrap( | 177 frame_.reset(webrtc::SharedDesktopFrame::Wrap( |
| 176 new webrtc::BasicDesktopFrame(source_size))); | 178 new webrtc::BasicDesktopFrame(source_size))); |
| 177 } | 179 } |
| 178 } | 180 } |
| 179 | 181 |
| 180 // Render the result into a new DesktopFrame instance that shares buffer with | 182 // Render the result into a new DesktopFrame instance that shares buffer with |
| 181 // |frame_|. updated_region() will be updated for |new_frame|, but not for | 183 // |frame_|. updated_region() will be updated for |new_frame|, but not for |
| 182 // |frame_|. | 184 // |frame_|. |
| 183 scoped_ptr<webrtc::DesktopFrame> new_frame(frame_->Share()); | 185 std::unique_ptr<webrtc::DesktopFrame> new_frame(frame_->Share()); |
| 184 | 186 |
| 185 { | 187 { |
| 186 base::AutoLock auto_lock(lock_); | 188 base::AutoLock auto_lock(lock_); |
| 187 if (!decoder_->DecodePacket(*packet, new_frame.get())) { | 189 if (!decoder_->DecodePacket(*packet, new_frame.get())) { |
| 188 LOG(ERROR) << "Decoder::DecodePacket() failed."; | 190 LOG(ERROR) << "Decoder::DecodePacket() failed."; |
| 189 return; | 191 return; |
| 190 } | 192 } |
| 191 } | 193 } |
| 192 | 194 |
| 193 main_task_runner_->PostTask(FROM_HERE, done); | 195 main_task_runner_->PostTask(FROM_HERE, done); |
| 194 | 196 |
| 195 if (save_frame_data_to_disk_) { | 197 if (save_frame_data_to_disk_) { |
| 196 scoped_ptr<webrtc::DesktopFrame> frame( | 198 std::unique_ptr<webrtc::DesktopFrame> frame( |
| 197 webrtc::BasicDesktopFrame::CopyOf(*frame_)); | 199 webrtc::BasicDesktopFrame::CopyOf(*frame_)); |
| 198 video_frame_writer.HighlightRectInFrame(frame.get(), expected_rect_); | 200 video_frame_writer.HighlightRectInFrame(frame.get(), expected_rect_); |
| 199 video_frame_writer.WriteFrameToDefaultPath(*frame); | 201 video_frame_writer.WriteFrameToDefaultPath(*frame); |
| 200 } | 202 } |
| 201 | 203 |
| 202 // Check to see if a image pattern matched reply is passed in, and whether | 204 // Check to see if a image pattern matched reply is passed in, and whether |
| 203 // the |expected_rect_| falls within the current frame. | 205 // the |expected_rect_| falls within the current frame. |
| 204 if (image_pattern_matched_callback_.is_null() || | 206 if (image_pattern_matched_callback_.is_null() || |
| 205 expected_rect_.right() > frame_->size().width() || | 207 expected_rect_.right() > frame_->size().width() || |
| 206 expected_rect_.bottom() > frame_->size().height()) { | 208 expected_rect_.bottom() > frame_->size().height()) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 VLOG(2) << "TestVideoRenderer::GetVideoStub() Called"; | 308 VLOG(2) << "TestVideoRenderer::GetVideoStub() Called"; |
| 307 return this; | 309 return this; |
| 308 } | 310 } |
| 309 | 311 |
| 310 protocol::FrameConsumer* TestVideoRenderer::GetFrameConsumer() { | 312 protocol::FrameConsumer* TestVideoRenderer::GetFrameConsumer() { |
| 311 DCHECK(thread_checker_.CalledOnValidThread()); | 313 DCHECK(thread_checker_.CalledOnValidThread()); |
| 312 NOTREACHED(); | 314 NOTREACHED(); |
| 313 return nullptr; | 315 return nullptr; |
| 314 } | 316 } |
| 315 | 317 |
| 316 void TestVideoRenderer::ProcessVideoPacket(scoped_ptr<VideoPacket> video_packet, | 318 void TestVideoRenderer::ProcessVideoPacket( |
| 317 const base::Closure& done) { | 319 std::unique_ptr<VideoPacket> video_packet, |
| 320 const base::Closure& done) { |
| 318 DCHECK(thread_checker_.CalledOnValidThread()); | 321 DCHECK(thread_checker_.CalledOnValidThread()); |
| 319 DCHECK(video_decode_task_runner_) << "Failed to start video decode thread"; | 322 DCHECK(video_decode_task_runner_) << "Failed to start video decode thread"; |
| 320 | 323 |
| 321 if (video_packet->has_data() && video_packet->data().size() != 0) { | 324 if (video_packet->has_data() && video_packet->data().size() != 0) { |
| 322 VLOG(2) << "process video packet is called!"; | 325 VLOG(2) << "process video packet is called!"; |
| 323 | 326 |
| 324 // Post video process task to the video decode thread. | 327 // Post video process task to the video decode thread. |
| 325 base::Closure process_video_task = base::Bind( | 328 base::Closure process_video_task = base::Bind( |
| 326 &TestVideoRenderer::Core::ProcessVideoPacket, | 329 &TestVideoRenderer::Core::ProcessVideoPacket, |
| 327 base::Unretained(core_.get()), base::Passed(&video_packet), done); | 330 base::Unretained(core_.get()), base::Passed(&video_packet), done); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 338 const protocol::ChannelConfig::Codec codec) { | 341 const protocol::ChannelConfig::Codec codec) { |
| 339 DCHECK(thread_checker_.CalledOnValidThread()); | 342 DCHECK(thread_checker_.CalledOnValidThread()); |
| 340 | 343 |
| 341 VLOG(2) << "TestVideoRenderer::SetDecoder() Called"; | 344 VLOG(2) << "TestVideoRenderer::SetDecoder() Called"; |
| 342 video_decode_task_runner_->PostTask( | 345 video_decode_task_runner_->PostTask( |
| 343 FROM_HERE, base::Bind(&Core::SetCodecForDecoding, | 346 FROM_HERE, base::Bind(&Core::SetCodecForDecoding, |
| 344 base::Unretained(core_.get()), | 347 base::Unretained(core_.get()), |
| 345 codec)); | 348 codec)); |
| 346 } | 349 } |
| 347 | 350 |
| 348 scoped_ptr<webrtc::DesktopFrame> TestVideoRenderer::GetCurrentFrameForTest() | 351 std::unique_ptr<webrtc::DesktopFrame> |
| 349 const { | 352 TestVideoRenderer::GetCurrentFrameForTest() const { |
| 350 DCHECK(thread_checker_.CalledOnValidThread()); | 353 DCHECK(thread_checker_.CalledOnValidThread()); |
| 351 | 354 |
| 352 return core_->GetCurrentFrameForTest(); | 355 return core_->GetCurrentFrameForTest(); |
| 353 } | 356 } |
| 354 | 357 |
| 355 void TestVideoRenderer::ExpectAverageColorInRect( | 358 void TestVideoRenderer::ExpectAverageColorInRect( |
| 356 const webrtc::DesktopRect& expected_rect, | 359 const webrtc::DesktopRect& expected_rect, |
| 357 const RGBValue& expected_avg_color, | 360 const RGBValue& expected_avg_color, |
| 358 const base::Closure& image_pattern_matched_callback) { | 361 const base::Closure& image_pattern_matched_callback) { |
| 359 DCHECK(thread_checker_.CalledOnValidThread()); | 362 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 371 DCHECK(thread_checker_.CalledOnValidThread()); | 374 DCHECK(thread_checker_.CalledOnValidThread()); |
| 372 | 375 |
| 373 video_decode_task_runner_->PostTask( | 376 video_decode_task_runner_->PostTask( |
| 374 FROM_HERE, | 377 FROM_HERE, |
| 375 base::Bind(&Core::save_frame_data_to_disk, base::Unretained(core_.get()), | 378 base::Bind(&Core::save_frame_data_to_disk, base::Unretained(core_.get()), |
| 376 save_frame_data_to_disk)); | 379 save_frame_data_to_disk)); |
| 377 } | 380 } |
| 378 | 381 |
| 379 } // namespace test | 382 } // namespace test |
| 380 } // namespace remoting | 383 } // namespace remoting |
| OLD | NEW |