| Index: remoting/protocol/host_video_dispatcher.cc
|
| diff --git a/remoting/protocol/host_video_dispatcher.cc b/remoting/protocol/host_video_dispatcher.cc
|
| index b9a12c0294f28ac8e95d65ca52c8e6c000e8334f..95778e13eeb90cc8537d80cd7641db6b62c14edd 100644
|
| --- a/remoting/protocol/host_video_dispatcher.cc
|
| +++ b/remoting/protocol/host_video_dispatcher.cc
|
| @@ -5,24 +5,84 @@
|
| #include "remoting/protocol/host_video_dispatcher.h"
|
|
|
| #include "base/bind.h"
|
| +#include "base/callback_helpers.h"
|
| #include "net/socket/stream_socket.h"
|
| #include "remoting/base/constants.h"
|
| -#include "remoting/proto/video.pb.h"
|
| +#include "remoting/protocol/errors.h"
|
| #include "remoting/protocol/message_serialization.h"
|
|
|
| namespace remoting {
|
| namespace protocol {
|
|
|
| +HostVideoDispatcher::PendingFrame::PendingFrame(
|
| + int frame_id,
|
| + const ProgressCallback& progress_callback)
|
| + : frame_id(frame_id), progress_callback(progress_callback) {
|
| +}
|
| +
|
| HostVideoDispatcher::HostVideoDispatcher()
|
| - : ChannelDispatcherBase(kVideoChannelName) {
|
| + : ChannelDispatcherBase(kVideoChannelName),
|
| + frame_id_(0),
|
| + parser_(
|
| + base::Bind(&HostVideoDispatcher::OnVideoAck, base::Unretained(this)),
|
| + reader()) {
|
| }
|
|
|
| HostVideoDispatcher::~HostVideoDispatcher() {
|
| }
|
|
|
| -void HostVideoDispatcher::ProcessVideoPacket(scoped_ptr<VideoPacket> packet,
|
| - const base::Closure& done) {
|
| - writer()->Write(SerializeAndFrameMessage(*packet), done);
|
| +void HostVideoDispatcher::ProcessVideoPacket(
|
| + scoped_ptr<VideoPacket> packet,
|
| + const ProgressCallback& progress_callback) {
|
| + if (SupportsAcks()) {
|
| + packet->set_frame_id(frame_id_);
|
| + pending_frames_.push_back(PendingFrame(frame_id_, progress_callback));
|
| + frame_id_++;
|
| + }
|
| +
|
| + writer()->Write(
|
| + SerializeAndFrameMessage(*packet),
|
| + base::Bind(&HostVideoDispatcher::OnPacketSent, base::Unretained(this),
|
| + progress_callback));
|
| +}
|
| +
|
| +bool HostVideoDispatcher::SupportsAcks() {
|
| + return channel_config().version > kVideoStreamVersionNoAck;
|
| +}
|
| +
|
| +void HostVideoDispatcher::OnPacketSent(
|
| + const ProgressCallback& progress_callback) {
|
| + progress_callback.Run(PacketProgress::SENT);
|
| +
|
| + // For older clients that don't send explicit video Ack message call notify
|
| + // DONE state as soon as the frame is pushed to the channel.
|
| + if (!SupportsAcks())
|
| + progress_callback.Run(PacketProgress::DONE);
|
| +}
|
| +
|
| +void HostVideoDispatcher::OnVideoAck(scoped_ptr<VideoAck> ack,
|
| + const base::Closure& done) {
|
| + base::ScopedClosureRunner done_runner(done);
|
| +
|
| + if (!SupportsAcks()) {
|
| + LOG(ERROR) << "Unexpected VideoAck message received.";
|
| + return;
|
| + }
|
| +
|
| + if (pending_frames_.empty() ||
|
| + pending_frames_.front().frame_id != ack->frame_id()) {
|
| + NotifyError(INCOMPATIBLE_PROTOCOL);
|
| + return;
|
| + }
|
| +
|
| + // TODO(sergeyu): Currently the latency information in |ack| is ignored.
|
| + // Expose it from this class so that CaptureScheduler can utilize it somehow.
|
| + // See crbug.com/453177 .
|
| +
|
| + ProgressCallback progress_callback =
|
| + pending_frames_.front().progress_callback;
|
| + pending_frames_.pop_front();
|
| + progress_callback.Run(PacketProgress::DONE);
|
| }
|
|
|
| } // namespace protocol
|
|
|