#ifndef REMOTING_PROTOCOL_VIDEO_FRAME_PUMP_H_
#define REMOTING_PROTOCOL_VIDEO_FRAME_PUMP_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "remoting/codec/video_encoder.h"
#include "remoting/proto/video.pb.h"
#include "remoting/protocol/capture_scheduler.h"
#include "remoting/protocol/desktop_capturer.h"
#include "remoting/protocol/video_stream.h"
namespace base {
class SingleThreadTaskRunner;
}
namespace remoting::protocol {
class VideoFeedbackStub;
class VideoStub;
class VideoFramePump : public VideoStream,
public webrtc::DesktopCapturer::Callback {
public:
VideoFramePump(scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner,
std::unique_ptr<DesktopCapturer> capturer,
std::unique_ptr<VideoEncoder> encoder,
protocol::VideoStub* video_stub);
VideoFramePump(const VideoFramePump&) = delete;
VideoFramePump& operator=(const VideoFramePump&) = delete;
~VideoFramePump() override;
void SetEventTimestampsSource(scoped_refptr<InputEventTimestampsSource>
event_timestamps_source) override;
void Pause(bool pause) override;
void SetObserver(Observer* observer) override;
void SelectSource(webrtc::ScreenId id) override;
void SetComposeEnabled(bool enabled) override;
void SetMouseCursor(
std::unique_ptr<webrtc::MouseCursor> mouse_cursor) override;
void SetMouseCursorPosition(const webrtc::DesktopVector& position) override;
void SetTargetFramerate(int framerate) override;
protocol::VideoFeedbackStub* video_feedback_stub() {
return &capture_scheduler_;
}
private:
struct FrameTimestamps {
FrameTimestamps();
~FrameTimestamps();
InputEventTimestamps input_event_timestamps;
base::TimeTicks capture_started_time;
base::TimeTicks capture_ended_time;
base::TimeTicks encode_started_time;
base::TimeTicks encode_ended_time;
base::TimeTicks can_send_time;
};
struct PacketWithTimestamps {
PacketWithTimestamps(std::unique_ptr<VideoPacket> packet,
std::unique_ptr<FrameTimestamps> timestamps);
~PacketWithTimestamps();
std::unique_ptr<VideoPacket> packet;
std::unique_ptr<FrameTimestamps> timestamps;
};
void OnCaptureResult(webrtc::DesktopCapturer::Result result,
std::unique_ptr<webrtc::DesktopFrame> frame) override;
void CaptureNextFrame();
static std::unique_ptr<PacketWithTimestamps> EncodeFrame(
VideoEncoder* encoder,
std::unique_ptr<webrtc::DesktopFrame> frame,
std::unique_ptr<FrameTimestamps> timestamps);
void OnFrameEncoded(std::unique_ptr<PacketWithTimestamps> packet);
void SendPacket(std::unique_ptr<PacketWithTimestamps> packet);
void UpdateFrameTimers(VideoPacket* packet, FrameTimestamps* timestamps);
void OnVideoPacketSent();
void SendKeepAlivePacket();
void OnKeepAlivePacketSent();
scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner_;
std::unique_ptr<DesktopCapturer> capturer_;
std::unique_ptr<VideoEncoder> encoder_;
scoped_refptr<InputEventTimestampsSource> event_timestamps_source_;
raw_ptr<protocol::VideoStub> video_stub_;
raw_ptr<Observer> observer_ = nullptr;
webrtc::DesktopSize frame_size_;
webrtc::DesktopVector frame_dpi_;
base::RetainingOneShotTimer keep_alive_timer_;
CaptureScheduler capture_scheduler_;
std::unique_ptr<FrameTimestamps> captured_frame_timestamps_;
bool send_pending_ = false;
std::vector<std::unique_ptr<PacketWithTimestamps>> pending_packets_;
THREAD_CHECKER(thread_checker_);
base::WeakPtrFactory<VideoFramePump> weak_factory_{this};
};
}
#endif