| 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/protocol/client_video_dispatcher.h" | 5 #include "remoting/protocol/client_video_dispatcher.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_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "net/socket/stream_socket.h" | 11 #include "net/socket/stream_socket.h" |
| 12 #include "remoting/base/compound_buffer.h" | 12 #include "remoting/base/compound_buffer.h" |
| 13 #include "remoting/base/constants.h" | 13 #include "remoting/base/constants.h" |
| 14 #include "remoting/proto/control.pb.h" |
| 14 #include "remoting/proto/video.pb.h" | 15 #include "remoting/proto/video.pb.h" |
| 16 #include "remoting/protocol/client_stub.h" |
| 15 #include "remoting/protocol/message_pipe.h" | 17 #include "remoting/protocol/message_pipe.h" |
| 16 #include "remoting/protocol/message_serialization.h" | 18 #include "remoting/protocol/message_serialization.h" |
| 17 #include "remoting/protocol/video_stub.h" | 19 #include "remoting/protocol/video_stub.h" |
| 18 | 20 |
| 19 namespace remoting { | 21 namespace remoting { |
| 20 namespace protocol { | 22 namespace protocol { |
| 21 | 23 |
| 22 struct ClientVideoDispatcher::PendingFrame { | 24 struct ClientVideoDispatcher::PendingFrame { |
| 23 PendingFrame(int frame_id) | 25 PendingFrame(int frame_id) |
| 24 : frame_id(frame_id), | 26 : frame_id(frame_id), |
| 25 done(false) {} | 27 done(false) {} |
| 26 int frame_id; | 28 int frame_id; |
| 27 bool done; | 29 bool done; |
| 28 }; | 30 }; |
| 29 | 31 |
| 30 ClientVideoDispatcher::ClientVideoDispatcher(VideoStub* video_stub) | 32 ClientVideoDispatcher::ClientVideoDispatcher(VideoStub* video_stub, |
| 33 ClientStub* client_stub) |
| 31 : ChannelDispatcherBase(kVideoChannelName), | 34 : ChannelDispatcherBase(kVideoChannelName), |
| 32 video_stub_(video_stub), | 35 video_stub_(video_stub), |
| 36 client_stub_(client_stub), |
| 33 weak_factory_(this) {} | 37 weak_factory_(this) {} |
| 38 |
| 34 ClientVideoDispatcher::~ClientVideoDispatcher() {} | 39 ClientVideoDispatcher::~ClientVideoDispatcher() {} |
| 35 | 40 |
| 36 void ClientVideoDispatcher::OnIncomingMessage( | 41 void ClientVideoDispatcher::OnIncomingMessage( |
| 37 scoped_ptr<CompoundBuffer> message) { | 42 scoped_ptr<CompoundBuffer> message) { |
| 38 scoped_ptr<VideoPacket> video_packet = | 43 scoped_ptr<VideoPacket> video_packet = |
| 39 ParseMessage<VideoPacket>(message.get()); | 44 ParseMessage<VideoPacket>(message.get()); |
| 40 if (!video_packet) | 45 if (!video_packet) |
| 41 return; | 46 return; |
| 42 | 47 |
| 43 int frame_id = video_packet->frame_id(); | 48 int frame_id = video_packet->frame_id(); |
| 44 | 49 |
| 45 if (!video_packet->has_frame_id()) { | 50 if (!video_packet->has_frame_id()) { |
| 46 video_stub_->ProcessVideoPacket(std::move(video_packet), | 51 video_stub_->ProcessVideoPacket(std::move(video_packet), |
| 47 base::Bind(&base::DoNothing)); | 52 base::Bind(&base::DoNothing)); |
| 48 return; | 53 return; |
| 49 } | 54 } |
| 50 | 55 |
| 56 bool resolution_changed = false; |
| 57 |
| 58 if (video_packet->format().has_screen_width() && |
| 59 video_packet->format().has_screen_height()) { |
| 60 webrtc::DesktopSize frame_size(video_packet->format().screen_width(), |
| 61 video_packet->format().screen_height()); |
| 62 if (!screen_size_.equals(frame_size)) { |
| 63 screen_size_ = frame_size; |
| 64 resolution_changed = true; |
| 65 } |
| 66 } |
| 67 |
| 68 if (video_packet->format().has_x_dpi() && |
| 69 video_packet->format().has_y_dpi()) { |
| 70 webrtc::DesktopVector screen_dpi(video_packet->format().x_dpi(), |
| 71 video_packet->format().y_dpi()); |
| 72 if (!screen_dpi_.equals(screen_dpi)) { |
| 73 screen_dpi_ = screen_dpi; |
| 74 resolution_changed = true; |
| 75 } |
| 76 } |
| 77 |
| 78 // Simulate DesktopLayout message whenever screen size/resolution changes. |
| 79 if (resolution_changed) { |
| 80 VideoLayout layout; |
| 81 VideoTrackLayout* video_track = layout.add_video_track(); |
| 82 video_track->set_position_x(0); |
| 83 video_track->set_position_y(0); |
| 84 video_track->set_width(screen_size_.width() * kDefaultDpi / |
| 85 screen_dpi_.x()); |
| 86 video_track->set_height(screen_size_.height() * kDefaultDpi / |
| 87 screen_dpi_.y()); |
| 88 video_track->set_x_dpi(screen_dpi_.x()); |
| 89 video_track->set_y_dpi(screen_dpi_.y()); |
| 90 client_stub_->SetVideoLayout(layout); |
| 91 } |
| 92 |
| 51 PendingFramesList::iterator pending_frame = | 93 PendingFramesList::iterator pending_frame = |
| 52 pending_frames_.insert(pending_frames_.end(), PendingFrame(frame_id)); | 94 pending_frames_.insert(pending_frames_.end(), PendingFrame(frame_id)); |
| 53 | 95 |
| 54 video_stub_->ProcessVideoPacket( | 96 video_stub_->ProcessVideoPacket( |
| 55 std::move(video_packet), | 97 std::move(video_packet), |
| 56 base::Bind(&ClientVideoDispatcher::OnPacketDone, | 98 base::Bind(&ClientVideoDispatcher::OnPacketDone, |
| 57 weak_factory_.GetWeakPtr(), pending_frame)); | 99 weak_factory_.GetWeakPtr(), pending_frame)); |
| 58 } | 100 } |
| 59 | 101 |
| 60 void ClientVideoDispatcher::OnPacketDone( | 102 void ClientVideoDispatcher::OnPacketDone( |
| 61 PendingFramesList::iterator pending_frame) { | 103 PendingFramesList::iterator pending_frame) { |
| 62 // Mark the frame as done. | 104 // Mark the frame as done. |
| 63 DCHECK(!pending_frame->done); | 105 DCHECK(!pending_frame->done); |
| 64 pending_frame->done = true; | 106 pending_frame->done = true; |
| 65 | 107 |
| 66 // Send VideoAck for all packets in the head of the queue that have finished | 108 // Send VideoAck for all packets in the head of the queue that have finished |
| 67 // rendering. | 109 // rendering. |
| 68 while (!pending_frames_.empty() && pending_frames_.front().done) { | 110 while (!pending_frames_.empty() && pending_frames_.front().done) { |
| 69 VideoAck ack_message; | 111 VideoAck ack_message; |
| 70 ack_message.set_frame_id(pending_frames_.front().frame_id); | 112 ack_message.set_frame_id(pending_frames_.front().frame_id); |
| 71 message_pipe()->Send(&ack_message, base::Closure()); | 113 message_pipe()->Send(&ack_message, base::Closure()); |
| 72 pending_frames_.pop_front(); | 114 pending_frames_.pop_front(); |
| 73 } | 115 } |
| 74 } | 116 } |
| 75 | 117 |
| 76 } // namespace protocol | 118 } // namespace protocol |
| 77 } // namespace remoting | 119 } // namespace remoting |
| OLD | NEW |