1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <chrono> 20 #include <memory> 21 #include <mutex> 22 #include <optional> 23 #include <thread> 24 25 #include "host/frontend/webrtc/cvd_video_frame_buffer.h" 26 #include "host/frontend/webrtc/libdevice/video_sink.h" 27 #include "host/frontend/webrtc/screenshot_handler.h" 28 #include "host/libs/screen_connector/screen_connector.h" 29 30 namespace cuttlefish { 31 /** 32 * ScreenConnectorImpl will generate this, and enqueue 33 * 34 * It's basically a (processed) frame, so it: 35 * must be efficiently std::move-able 36 * Also, for the sake of algorithm simplicity: 37 * must be default-constructable & assignable 38 * 39 */ 40 struct WebRtcScProcessedFrame : public ScreenConnectorFrameInfo { 41 // must support move semantic 42 std::unique_ptr<CvdVideoFrameBuffer> buf_; CloneWebRtcScProcessedFrame43 std::unique_ptr<WebRtcScProcessedFrame> Clone() { 44 // copy internal buffer, not move 45 CvdVideoFrameBuffer* new_buffer = new CvdVideoFrameBuffer(*(buf_.get())); 46 auto cloned_frame = std::make_unique<WebRtcScProcessedFrame>(); 47 cloned_frame->buf_ = std::unique_ptr<CvdVideoFrameBuffer>(new_buffer); 48 return cloned_frame; 49 } 50 }; 51 52 namespace webrtc_streaming { 53 class Streamer; 54 } // namespace webrtc_streaming 55 56 class DisplayHandler { 57 public: 58 using ScreenConnector = cuttlefish::ScreenConnector<WebRtcScProcessedFrame>; 59 using GenerateProcessedFrameCallback = 60 ScreenConnector::GenerateProcessedFrameCallback; 61 using WebRtcScProcessedFrame = cuttlefish::WebRtcScProcessedFrame; 62 63 DisplayHandler(webrtc_streaming::Streamer& streamer, 64 ScreenshotHandler& screenshot_handler, 65 ScreenConnector& screen_connector); 66 ~DisplayHandler(); 67 68 [[noreturn]] void Loop(); 69 70 // If std::nullopt, send last frame for all displays. 71 void SendLastFrame(std::optional<uint32_t> display_number); 72 73 void AddDisplayClient(); 74 void RemoveDisplayClient(); 75 76 private: 77 struct BufferInfo { 78 std::chrono::system_clock::time_point last_sent_time_stamp; 79 std::shared_ptr<webrtc_streaming::VideoFrameBuffer> buffer; 80 }; 81 enum class RepeaterState { 82 RUNNING, 83 STOPPED, 84 }; 85 86 GenerateProcessedFrameCallback GetScreenConnectorCallback(); 87 void SendBuffers(std::map<uint32_t, std::shared_ptr<BufferInfo>> buffers); 88 void RepeatFramesPeriodically(); 89 90 std::map<uint32_t, std::shared_ptr<webrtc_streaming::VideoSink>> 91 display_sinks_; 92 webrtc_streaming::Streamer& streamer_; 93 ScreenshotHandler& screenshot_handler_; 94 ScreenConnector& screen_connector_; 95 std::map<uint32_t, std::shared_ptr<BufferInfo>> display_last_buffers_; 96 std::mutex last_buffers_mutex_; 97 std::mutex send_mutex_; 98 std::thread frame_repeater_; 99 // Protected by repeater_state_mutex 100 RepeaterState repeater_state_ = RepeaterState::RUNNING; 101 // Protected by repeater_state_mutex 102 int num_active_clients_ = 0; 103 std::mutex repeater_state_mutex_; 104 std::condition_variable repeater_state_condvar_; 105 }; 106 } // namespace cuttlefish 107