blob: 0c607d7f3f7b1235c10afb348be3c1fd142461a2 [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
2 * Copyright (C) 2023 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
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010017#include "Util.h"
18
19#include <unistd.h>
20
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010021#include <algorithm>
22#include <array>
Jan Sebechlebsky43543222024-02-16 12:50:32 +010023#include <cstdint>
24#include <memory>
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010025
Jan Sebechlebsky43543222024-02-16 12:50:32 +010026#include "android/hardware_buffer.h"
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010027#include "jpeglib.h"
Jan Sebechlebsky43543222024-02-16 12:50:32 +010028#include "ui/GraphicBuffer.h"
29#include "utils/Errors.h"
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010030
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010031namespace android {
32namespace companion {
33namespace virtualcamera {
34
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010035using ::aidl::android::companion::virtualcamera::Format;
36using ::aidl::android::hardware::common::NativeHandle;
37
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010038// Lower bound for maximal supported texture size is at least 2048x2048
39// but on most platforms will be more.
40// TODO(b/301023410) - Query actual max texture size.
41constexpr int kMaxTextureSize = 2048;
42constexpr int kLibJpegDctSize = DCTSIZE;
Biswarup Pal6152a302023-12-19 12:44:09 +000043constexpr int kMaxFpsUpperLimit = 60;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010044
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010045constexpr std::array<Format, 2> kSupportedFormats{Format::YUV_420_888,
46 Format::RGBA_8888};
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010047
Jan Sebechlebsky43543222024-02-16 12:50:32 +010048YCbCrLockGuard::YCbCrLockGuard(std::shared_ptr<AHardwareBuffer> hwBuffer,
49 const uint32_t usageFlags)
50 : mHwBuffer(hwBuffer) {
51 GraphicBuffer* gBuffer = GraphicBuffer::fromAHardwareBuffer(mHwBuffer.get());
52 if (gBuffer == nullptr) {
53 ALOGE("%s: Attempting to lock nullptr buffer.", __func__);
54 return;
55 }
56 mLockStatus = gBuffer->lockYCbCr(usageFlags, &mYCbCr);
57 if (mLockStatus != OK) {
58 ALOGE("%s: Failed to lock graphic buffer: %s", __func__,
59 statusToString(mLockStatus).c_str());
60 }
61}
62
63YCbCrLockGuard::~YCbCrLockGuard() {
64 if (getStatus() != OK) {
65 return;
66 }
67
68 GraphicBuffer* gBuffer = GraphicBuffer::fromAHardwareBuffer(mHwBuffer.get());
69 if (gBuffer == nullptr) {
70 return;
71 }
72 gBuffer->unlock();
73 status_t status = gBuffer->unlock();
74 if (status != NO_ERROR) {
75 ALOGE("Failed to unlock graphic buffer: %s", statusToString(status).c_str());
76 }
77}
78
79status_t YCbCrLockGuard::getStatus() const {
80 return mLockStatus;
81}
82
83const android_ycbcr& YCbCrLockGuard::operator*() const {
84 LOG_ALWAYS_FATAL_IF(getStatus() != OK,
85 "Dereferencing unlocked YCbCrLockGuard, status is %s",
86 statusToString(mLockStatus).c_str());
87 return mYCbCr;
88}
89
90PlanesLockGuard::PlanesLockGuard(std::shared_ptr<AHardwareBuffer> hwBuffer,
91 const uint64_t usageFlags, sp<Fence> fence) {
92 if (hwBuffer == nullptr) {
93 ALOGE("%s: Attempting to lock nullptr buffer.", __func__);
94 return;
95 }
96
97 const int32_t rawFence = fence != nullptr ? fence->get() : -1;
98 mLockStatus = static_cast<status_t>(AHardwareBuffer_lockPlanes(
99 hwBuffer.get(), usageFlags, rawFence, nullptr, &mPlanes));
100 if (mLockStatus != OK) {
101 ALOGE("%s: Failed to lock graphic buffer: %s", __func__,
102 statusToString(mLockStatus).c_str());
103 }
104}
105
106PlanesLockGuard::~PlanesLockGuard() {
107 if (getStatus() != OK || mHwBuffer == nullptr) {
108 return;
109 }
110 AHardwareBuffer_unlock(mHwBuffer.get(), /*fence=*/nullptr);
111}
112
113int PlanesLockGuard::getStatus() const {
114 return mLockStatus;
115}
116
117const AHardwareBuffer_Planes& PlanesLockGuard::operator*() const {
118 LOG_ALWAYS_FATAL_IF(getStatus() != OK,
119 "Dereferencing unlocked PlanesLockGuard, status is %s",
120 statusToString(mLockStatus).c_str());
121 return mPlanes;
122}
123
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100124sp<Fence> importFence(const NativeHandle& aidlHandle) {
125 if (aidlHandle.fds.size() != 1) {
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100126 return sp<Fence>::make();
127 }
128
129 return sp<Fence>::make(::dup(aidlHandle.fds[0].get()));
130}
131
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100132bool isPixelFormatSupportedForInput(const Format format) {
133 return std::find(kSupportedFormats.begin(), kSupportedFormats.end(),
134 format) != kSupportedFormats.end();
135}
136
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100137// Returns true if specified format is supported for virtual camera input.
138bool isFormatSupportedForInput(const int width, const int height,
Biswarup Pal6152a302023-12-19 12:44:09 +0000139 const Format format, const int maxFps) {
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100140 if (!isPixelFormatSupportedForInput(format)) {
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100141 return false;
142 }
143
144 if (width <= 0 || height <= 0 || width > kMaxTextureSize ||
145 height > kMaxTextureSize) {
146 return false;
147 }
148
Biswarup Pal6152a302023-12-19 12:44:09 +0000149 if (maxFps <= 0 || maxFps > kMaxFpsUpperLimit) {
150 return false;
151 }
152
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100153 return true;
154}
155
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100156std::ostream& operator<<(std::ostream& os, const Resolution& resolution) {
157 return os << resolution.width << "x" << resolution.height;
158}
159
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100160} // namespace virtualcamera
161} // namespace companion
162} // namespace android