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 |