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/ring_buffer_manager.h" 29 #include "host/libs/screen_connector/screen_connector.h" 30 31 namespace cuttlefish { 32 class CompositionManager; 33 /** 34 * ScreenConnectorImpl will generate this, and enqueue 35 * 36 * It's basically a (processed) frame, so it: 37 * must be efficiently std::move-able 38 * Also, for the sake of algorithm simplicity: 39 * must be default-constructable & assignable 40 * 41 */ 42 struct WebRtcScProcessedFrame : public ScreenConnectorFrameInfo { 43 // must support move semantic 44 std::unique_ptr<CvdVideoFrameBuffer> buf_; CloneWebRtcScProcessedFrame45 std::unique_ptr<WebRtcScProcessedFrame> Clone() { 46 // copy internal buffer, not move 47 CvdVideoFrameBuffer* new_buffer = new CvdVideoFrameBuffer(*(buf_.get())); 48 auto cloned_frame = std::make_unique<WebRtcScProcessedFrame>(); 49 cloned_frame->buf_ = std::unique_ptr<CvdVideoFrameBuffer>(new_buffer); 50 return cloned_frame; 51 } 52 }; 53 54 namespace webrtc_streaming { 55 class Streamer; 56 } // namespace webrtc_streaming 57 58 class DisplayHandler { 59 public: 60 using ScreenConnector = cuttlefish::ScreenConnector<WebRtcScProcessedFrame>; 61 using GenerateProcessedFrameCallback = 62 ScreenConnector::GenerateProcessedFrameCallback; 63 using WebRtcScProcessedFrame = cuttlefish::WebRtcScProcessedFrame; 64 65 DisplayHandler( 66 webrtc_streaming::Streamer& streamer, 67 ScreenshotHandler& screenshot_handler, ScreenConnector& screen_connector, 68 std::optional<std::unique_ptr<CompositionManager>> composition_manager); 69 ~DisplayHandler(); 70 71 [[noreturn]] void Loop(); 72 // If std::nullopt, send last frame for all displays. 73 void SendLastFrame(std::optional<uint32_t> display_number); 74 75 void AddDisplayClient(); 76 void RemoveDisplayClient(); 77 78 private: 79 struct BufferInfo { 80 std::chrono::system_clock::time_point last_sent_time_stamp; 81 std::shared_ptr<webrtc_streaming::VideoFrameBuffer> buffer; 82 }; 83 enum class RepeaterState { 84 RUNNING, 85 STOPPED, 86 }; 87 GenerateProcessedFrameCallback GetScreenConnectorCallback(); 88 void SendBuffers(std::map<uint32_t, std::shared_ptr<BufferInfo>> buffers); 89 void RepeatFramesPeriodically(); 90 91 std::optional<std::unique_ptr<CompositionManager>> composition_manager_; 92 std::map<uint32_t, std::shared_ptr<webrtc_streaming::VideoSink>> 93 display_sinks_; 94 webrtc_streaming::Streamer& streamer_; 95 ScreenshotHandler& screenshot_handler_; 96 ScreenConnector& screen_connector_; 97 std::map<uint32_t, std::shared_ptr<BufferInfo>> display_last_buffers_; 98 std::mutex last_buffers_mutex_; 99 std::mutex send_mutex_; 100 std::thread frame_repeater_; 101 // Protected by repeater_state_mutex 102 RepeaterState repeater_state_ = RepeaterState::RUNNING; 103 // Protected by repeater_state_mutex 104 int num_active_clients_ = 0; 105 std::mutex repeater_state_mutex_; 106 std::condition_variable repeater_state_condvar_; 107 }; 108 } // namespace cuttlefish 109