| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/client/software_video_renderer.h" | 5 #include "remoting/client/software_video_renderer.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| 11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 16 #include "base/task_runner_util.h" | 16 #include "base/task_runner_util.h" |
| 17 #include "remoting/base/util.h" | 17 #include "remoting/base/util.h" |
| 18 #include "remoting/codec/video_decoder.h" | 18 #include "remoting/codec/video_decoder.h" |
| 19 #include "remoting/codec/video_decoder_verbatim.h" | 19 #include "remoting/codec/video_decoder_verbatim.h" |
| 20 #include "remoting/codec/video_decoder_vpx.h" | 20 #include "remoting/codec/video_decoder_vpx.h" |
| 21 #include "remoting/proto/video.pb.h" | 21 #include "remoting/proto/video.pb.h" |
| 22 #include "remoting/protocol/frame_consumer.h" | 22 #include "remoting/protocol/frame_consumer.h" |
| 23 #include "remoting/protocol/frame_stats.h" |
| 24 #include "remoting/protocol/performance_tracker.h" |
| 23 #include "remoting/protocol/session_config.h" | 25 #include "remoting/protocol/session_config.h" |
| 24 #include "third_party/libyuv/include/libyuv/convert_argb.h" | 26 #include "third_party/libyuv/include/libyuv/convert_argb.h" |
| 25 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 27 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| 26 | 28 |
| 27 using remoting::protocol::ChannelConfig; | 29 using remoting::protocol::ChannelConfig; |
| 28 using remoting::protocol::SessionConfig; | 30 using remoting::protocol::SessionConfig; |
| 29 | 31 |
| 30 namespace remoting { | 32 namespace remoting { |
| 31 | 33 |
| 32 namespace { | 34 namespace { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 return consumer_; | 118 return consumer_; |
| 117 } | 119 } |
| 118 | 120 |
| 119 void SoftwareVideoRenderer::ProcessVideoPacket( | 121 void SoftwareVideoRenderer::ProcessVideoPacket( |
| 120 std::unique_ptr<VideoPacket> packet, | 122 std::unique_ptr<VideoPacket> packet, |
| 121 const base::Closure& done) { | 123 const base::Closure& done) { |
| 122 DCHECK(thread_checker_.CalledOnValidThread()); | 124 DCHECK(thread_checker_.CalledOnValidThread()); |
| 123 | 125 |
| 124 base::ScopedClosureRunner done_runner(done); | 126 base::ScopedClosureRunner done_runner(done); |
| 125 | 127 |
| 126 if (perf_tracker_) | 128 std::unique_ptr<protocol::FrameStats> frame_stats(new protocol::FrameStats( |
| 127 perf_tracker_->RecordVideoPacketStats(*packet); | 129 protocol::FrameStats::GetForVideoPacket(*packet))); |
| 128 | 130 |
| 129 // If the video packet is empty then drop it. Empty packets are used to | 131 // If the video packet is empty then there is nothing to decode. Empty packets |
| 130 // maintain activity on the network. | 132 // are used to maintain activity on the network. Stats for such packets still |
| 133 // need to be reported. |
| 131 if (!packet->has_data() || packet->data().size() == 0) { | 134 if (!packet->has_data() || packet->data().size() == 0) { |
| 135 if (perf_tracker_) |
| 136 perf_tracker_->RecordVideoFrameStats(*frame_stats); |
| 132 return; | 137 return; |
| 133 } | 138 } |
| 134 | 139 |
| 135 if (packet->format().has_screen_width() && | 140 if (packet->format().has_screen_width() && |
| 136 packet->format().has_screen_height()) { | 141 packet->format().has_screen_height()) { |
| 137 source_size_.set(packet->format().screen_width(), | 142 source_size_.set(packet->format().screen_width(), |
| 138 packet->format().screen_height()); | 143 packet->format().screen_height()); |
| 139 } | 144 } |
| 140 | 145 |
| 141 if (packet->format().has_x_dpi() && packet->format().has_y_dpi()) { | 146 if (packet->format().has_x_dpi() && packet->format().has_y_dpi()) { |
| 142 webrtc::DesktopVector source_dpi(packet->format().x_dpi(), | 147 webrtc::DesktopVector source_dpi(packet->format().x_dpi(), |
| 143 packet->format().y_dpi()); | 148 packet->format().y_dpi()); |
| 144 if (!source_dpi.equals(source_dpi_)) { | 149 if (!source_dpi.equals(source_dpi_)) { |
| 145 source_dpi_ = source_dpi; | 150 source_dpi_ = source_dpi; |
| 146 } | 151 } |
| 147 } | 152 } |
| 148 | 153 |
| 149 if (source_size_.is_empty()) { | 154 if (source_size_.is_empty()) { |
| 150 LOG(ERROR) << "Received VideoPacket with unknown size."; | 155 LOG(ERROR) << "Received VideoPacket with unknown size."; |
| 151 return; | 156 return; |
| 152 } | 157 } |
| 153 | 158 |
| 154 std::unique_ptr<webrtc::DesktopFrame> frame = | 159 std::unique_ptr<webrtc::DesktopFrame> frame = |
| 155 consumer_->AllocateFrame(source_size_); | 160 consumer_->AllocateFrame(source_size_); |
| 156 frame->set_dpi(source_dpi_); | 161 frame->set_dpi(source_dpi_); |
| 157 | 162 |
| 158 int32_t frame_id = packet->frame_id(); | |
| 159 base::PostTaskAndReplyWithResult( | 163 base::PostTaskAndReplyWithResult( |
| 160 decode_task_runner_.get(), FROM_HERE, | 164 decode_task_runner_.get(), FROM_HERE, |
| 161 base::Bind(&DoDecodeFrame, decoder_.get(), base::Passed(&packet), | 165 base::Bind(&DoDecodeFrame, decoder_.get(), base::Passed(&packet), |
| 162 base::Passed(&frame)), | 166 base::Passed(&frame)), |
| 163 base::Bind(&SoftwareVideoRenderer::RenderFrame, | 167 base::Bind(&SoftwareVideoRenderer::RenderFrame, |
| 164 weak_factory_.GetWeakPtr(), frame_id, done_runner.Release())); | 168 weak_factory_.GetWeakPtr(), base::Passed(&frame_stats), |
| 169 done_runner.Release())); |
| 165 } | 170 } |
| 166 | 171 |
| 167 void SoftwareVideoRenderer::RenderFrame( | 172 void SoftwareVideoRenderer::RenderFrame( |
| 168 int32_t frame_id, | 173 std::unique_ptr<protocol::FrameStats> stats, |
| 169 const base::Closure& done, | 174 const base::Closure& done, |
| 170 std::unique_ptr<webrtc::DesktopFrame> frame) { | 175 std::unique_ptr<webrtc::DesktopFrame> frame) { |
| 171 DCHECK(thread_checker_.CalledOnValidThread()); | 176 DCHECK(thread_checker_.CalledOnValidThread()); |
| 172 | 177 |
| 173 if (perf_tracker_) | 178 stats->time_decoded = base::TimeTicks::Now(); |
| 174 perf_tracker_->OnFrameDecoded(frame_id); | |
| 175 | 179 |
| 176 if (!frame) { | 180 if (!frame) { |
| 177 if (!done.is_null()) | 181 if (!done.is_null()) |
| 178 done.Run(); | 182 done.Run(); |
| 179 return; | 183 return; |
| 180 } | 184 } |
| 181 | 185 |
| 182 consumer_->DrawFrame(std::move(frame), | 186 consumer_->DrawFrame( |
| 183 base::Bind(&SoftwareVideoRenderer::OnFrameRendered, | 187 std::move(frame), |
| 184 weak_factory_.GetWeakPtr(), frame_id, done)); | 188 base::Bind(&SoftwareVideoRenderer::OnFrameRendered, |
| 189 weak_factory_.GetWeakPtr(), base::Passed(&stats), done)); |
| 185 } | 190 } |
| 186 | 191 |
| 187 void SoftwareVideoRenderer::OnFrameRendered(int32_t frame_id, | 192 void SoftwareVideoRenderer::OnFrameRendered( |
| 188 const base::Closure& done) { | 193 std::unique_ptr<protocol::FrameStats> stats, |
| 194 const base::Closure& done) { |
| 189 DCHECK(thread_checker_.CalledOnValidThread()); | 195 DCHECK(thread_checker_.CalledOnValidThread()); |
| 190 | 196 |
| 197 stats->time_rendered = base::TimeTicks::Now(); |
| 191 if (perf_tracker_) | 198 if (perf_tracker_) |
| 192 perf_tracker_->OnFramePainted(frame_id); | 199 perf_tracker_->RecordVideoFrameStats(*stats); |
| 193 | 200 |
| 194 if (!done.is_null()) | 201 if (!done.is_null()) |
| 195 done.Run(); | 202 done.Run(); |
| 196 } | 203 } |
| 197 | 204 |
| 198 } // namespace remoting | 205 } // namespace remoting |
| OLD | NEW |