| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <webrtc/ServerState.h> |
| |
| #include <webrtc/OpusPacketizer.h> |
| #include <webrtc/VP8Packetizer.h> |
| |
| #include <source/AudioSource.h> |
| #include <source/TouchSink.h> |
| #include <source/FrameBufferSource.h> |
| |
| #include "host/libs/config/cuttlefish_config.h" |
| |
| #include <gflags/gflags.h> |
| |
| DECLARE_int32(keyboard_fd); |
| DECLARE_int32(touch_fd); |
| DECLARE_int32(frame_server_fd); |
| DECLARE_bool(write_virtio_input); |
| |
| ServerState::ServerState( |
| std::shared_ptr<RunLoop> runLoop, VideoFormat videoFormat) |
| : |
| mRunLoop(runLoop), |
| mVideoFormat(videoFormat) { |
| |
| auto config = vsoc::CuttlefishConfig::Get(); |
| |
| android::FrameBufferSource::Format fbSourceFormat; |
| switch (videoFormat) { |
| case VideoFormat::VP8: |
| fbSourceFormat = android::FrameBufferSource::Format::VP8; |
| break; |
| default: |
| LOG(FATAL) << "Should not be here."; |
| } |
| |
| mFrameBufferSource = |
| std::make_shared<android::FrameBufferSource>(fbSourceFormat); |
| |
| int32_t screenParams[4]; |
| screenParams[0] = config->x_res(); |
| screenParams[1] = config->y_res(); |
| screenParams[2] = config->dpi(); |
| screenParams[3] = config->refresh_rate_hz(); |
| |
| static_cast<android::FrameBufferSource *>( |
| mFrameBufferSource.get())->setScreenParams(screenParams); |
| |
| mScreenConnector = std::shared_ptr<cvd::ScreenConnector>( |
| cvd::ScreenConnector::Get(FLAGS_frame_server_fd)); |
| mScreenConnectorMonitor.reset( |
| new std::thread([this]() { MonitorScreenConnector(); })); |
| |
| mAudioSource = std::make_shared<android::AudioSource>( |
| android::AudioSource::Format::OPUS); |
| |
| CHECK_GE(FLAGS_touch_fd, 0); |
| |
| auto touchSink = std::make_shared<android::TouchSink>( |
| mRunLoop, FLAGS_touch_fd, FLAGS_write_virtio_input); |
| |
| touchSink->start(); |
| |
| mTouchSink = touchSink; |
| |
| auto keyboardSink = std::make_shared<android::KeyboardSink>( |
| mRunLoop, FLAGS_keyboard_fd, FLAGS_write_virtio_input); |
| |
| keyboardSink->start(); |
| |
| mKeyboardSink = keyboardSink; |
| } |
| |
| void ServerState::MonitorScreenConnector() { |
| std::uint32_t last_frame = 0; |
| while (true) { |
| mScreenConnector->OnFrameAfter(last_frame, [this, &last_frame]( |
| std::uint32_t frame_num, |
| std::uint8_t *data) { |
| mRunLoop->postAndAwait([this, data]() { |
| static_cast<android::FrameBufferSource *>(mFrameBufferSource.get()) |
| ->injectFrame(data, cvd::ScreenConnector::ScreenSizeInBytes()); |
| }); |
| last_frame = frame_num; |
| }); |
| } |
| } |
| |
| std::shared_ptr<Packetizer> ServerState::getVideoPacketizer() { |
| auto packetizer = mVideoPacketizer.lock(); |
| if (!packetizer) { |
| switch (mVideoFormat) { |
| case VideoFormat::VP8: |
| { |
| packetizer = std::make_shared<VP8Packetizer>( |
| mRunLoop, mFrameBufferSource); |
| break; |
| } |
| |
| default: |
| LOG(FATAL) << "Should not be here."; |
| } |
| |
| packetizer->run(); |
| |
| mVideoPacketizer = packetizer; |
| } |
| |
| return packetizer; |
| } |
| |
| std::shared_ptr<Packetizer> ServerState::getAudioPacketizer() { |
| auto packetizer = mAudioPacketizer.lock(); |
| if (!packetizer) { |
| packetizer = std::make_shared<OpusPacketizer>(mRunLoop, mAudioSource); |
| packetizer->run(); |
| |
| mAudioPacketizer = packetizer; |
| } |
| |
| return packetizer; |
| } |
| |
| size_t ServerState::acquireHandlerId() { |
| size_t id = 0; |
| while (!mAllocatedHandlerIds.insert(id).second) { |
| ++id; |
| } |
| |
| return id; |
| } |
| |
| void ServerState::releaseHandlerId(size_t id) { |
| CHECK_EQ(mAllocatedHandlerIds.erase(id), 1); |
| } |
| |
| std::shared_ptr<android::TouchSink> ServerState::getTouchSink() { |
| return mTouchSink; |
| } |
| |
| std::shared_ptr<android::KeyboardSink> ServerState::getKeyboardSink() { |
| return mKeyboardSink; |
| } |