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
3 // found in the LICENSE file.
5 #include "remoting/protocol/client_video_dispatcher.h"
8 #include "base/callback_helpers.h"
9 #include "net/socket/stream_socket.h"
10 #include "remoting/base/constants.h"
11 #include "remoting/proto/video.pb.h"
12 #include "remoting/protocol/message_serialization.h"
13 #include "remoting/protocol/video_stub.h"
18 struct ClientVideoDispatcher::PendingFrame
{
19 PendingFrame(int frame_id
)
26 ClientVideoDispatcher::ClientVideoDispatcher(VideoStub
* video_stub
)
27 : ChannelDispatcherBase(kVideoChannelName
),
28 video_stub_(video_stub
),
29 parser_(base::Bind(&ClientVideoDispatcher::ProcessVideoPacket
,
30 base::Unretained(this)),
35 ClientVideoDispatcher::~ClientVideoDispatcher() {
38 void ClientVideoDispatcher::ProcessVideoPacket(
39 scoped_ptr
<VideoPacket
> video_packet
,
40 const base::Closure
& done
) {
41 base::ScopedClosureRunner
done_runner(done
);
43 int frame_id
= video_packet
->frame_id();
45 if (!video_packet
->has_frame_id()) {
46 video_stub_
->ProcessVideoPacket(video_packet
.Pass(), done_runner
.Release());
50 PendingFramesList::iterator pending_frame
=
51 pending_frames_
.insert(pending_frames_
.end(), PendingFrame(frame_id
));
53 video_stub_
->ProcessVideoPacket(
55 base::Bind(&ClientVideoDispatcher::OnPacketDone
,
56 weak_factory_
.GetWeakPtr(), pending_frame
));
59 void ClientVideoDispatcher::OnPacketDone(
60 PendingFramesList::iterator pending_frame
) {
61 // Mark the frame as done.
62 DCHECK(!pending_frame
->done
);
63 pending_frame
->done
= true;
65 // Send VideoAck for all packets in the head of the queue that have finished
67 while (!pending_frames_
.empty() && pending_frames_
.front().done
) {
69 ack_message
.set_frame_id(pending_frames_
.front().frame_id
);
70 writer()->Write(SerializeAndFrameMessage(ack_message
), base::Closure());
71 pending_frames_
.pop_front();
75 } // namespace protocol
76 } // namespace remoting