1dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph/* 2dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * Copyright (C) 2016 The Android Open Source Project 3dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * 4dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * Licensed under the Apache License, Version 2.0 (the "License"); 5dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * you may not use this file except in compliance with the License. 6dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * You may obtain a copy of the License at 7dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * 8dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * http://www.apache.org/licenses/LICENSE-2.0 9dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * 10dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * Unless required by applicable law or agreed to in writing, software 11dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * distributed under the License is distributed on an "AS IS" BASIS, 12dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * See the License for the specific language governing permissions and 14dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * limitations under the License. 15dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph */ 16dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 17dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph#include "HalCamera.h" 18dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph#include "VirtualCamera.h" 19da289be96177f528495cc660f83472ade76c5918Scott Randolph#include "Enumerator.h" 20dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 21dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph#include <ui/GraphicBufferAllocator.h> 22dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph#include <ui/GraphicBufferMapper.h> 23dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 24dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 25dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace android { 26dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace automotive { 27dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace evs { 28dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace V1_0 { 29dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace implementation { 30dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 31dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 3229803803b299652fc219713774181dd9a7dd8decScott Randolph// TODO: We need to hook up death monitoring to detect stream death so we can attempt a reconnect 3329803803b299652fc219713774181dd9a7dd8decScott Randolph 3429803803b299652fc219713774181dd9a7dd8decScott Randolph 35dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphsp<VirtualCamera> HalCamera::makeVirtualCamera() { 36dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 37dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Create the client camera interface object 38dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph sp<VirtualCamera> client = new VirtualCamera(this); 39dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (client == nullptr) { 40dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGE("Failed to create client camera object"); 41dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return nullptr; 42dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 43dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 44dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Make sure we have enough buffers available for all our clients 45dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (!changeFramesInFlight(client->getAllowedBuffers())) { 46dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Gah! We couldn't get enough buffers, so we can't support this client 47dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Null the pointer, dropping our reference, thus destroying the client object 48dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph client = nullptr; 49dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return nullptr; 50dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 51dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 5229803803b299652fc219713774181dd9a7dd8decScott Randolph // Add this client to our ownership list via weak pointer 53dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mClients.push_back(client); 54dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 5529803803b299652fc219713774181dd9a7dd8decScott Randolph // Return the strong pointer to the client 56dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return client; 57dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 58dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 59dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 60dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphvoid HalCamera::disownVirtualCamera(sp<VirtualCamera> virtualCamera) { 61dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Ignore calls with null pointers 62dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (virtualCamera.get() == nullptr) { 6329803803b299652fc219713774181dd9a7dd8decScott Randolph ALOGW("Ignoring disownVirtualCamera call with null pointer"); 64dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return; 65dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 66dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 67dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Make sure the virtual camera's stream is stopped 68dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph virtualCamera->stopVideoStream(); 69dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 70dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Remove the virtual camera from our client list 7129803803b299652fc219713774181dd9a7dd8decScott Randolph unsigned clientCount = mClients.size(); 72dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mClients.remove(virtualCamera); 7329803803b299652fc219713774181dd9a7dd8decScott Randolph if (clientCount != mClients.size() + 1) { 7429803803b299652fc219713774181dd9a7dd8decScott Randolph ALOGE("Couldn't find camera in our client list to remove it"); 7529803803b299652fc219713774181dd9a7dd8decScott Randolph } 76dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph virtualCamera->shutdown(); 77dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 78dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Recompute the number of buffers required with the target camera removed from the list 79dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (!changeFramesInFlight(0)) { 80dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGE("Error when trying to reduce the in flight buffer count"); 81dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 82dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 83dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 84dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 85dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphbool HalCamera::changeFramesInFlight(int delta) { 86dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Walk all our clients and count their currently required frames 87dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph unsigned bufferCount = 0; 88dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph for (auto&& client : mClients) { 8929803803b299652fc219713774181dd9a7dd8decScott Randolph sp<VirtualCamera> virtCam = client.promote(); 9029803803b299652fc219713774181dd9a7dd8decScott Randolph if (virtCam != nullptr) { 9129803803b299652fc219713774181dd9a7dd8decScott Randolph bufferCount += virtCam->getAllowedBuffers(); 9229803803b299652fc219713774181dd9a7dd8decScott Randolph } 93dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 94dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 95dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Add the requested delta 96dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph bufferCount += delta; 97dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 98dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Never drop below 1 buffer -- even if all client cameras get closed 99dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (bufferCount < 1) { 100dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph bufferCount = 1; 101dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 102dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 103dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Ask the hardware for the resulting buffer count 104dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph Return<EvsResult> result = mHwCamera->setMaxFramesInFlight(bufferCount); 105dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph bool success = (result.isOk() && result == EvsResult::OK); 106dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 107dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Update the size of our array of outstanding frame records 108dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (success) { 109dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph std::vector<FrameRecord> newRecords; 110dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph newRecords.reserve(bufferCount); 111dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 112dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Copy and compact the old records that are still active 113dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph for (const auto& rec : mFrames) { 114dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (rec.refCount > 0) { 115dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph newRecords.emplace_back(rec); 116dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 117dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 118dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (newRecords.size() > (unsigned)bufferCount) { 119dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGW("We found more frames in use than requested."); 120dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 121dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 122dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mFrames.swap(newRecords); 123dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 124dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 125dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return success; 126dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 127dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 128dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 129dcc3534f0f7523e4ee7285522586d6e2827aa407Scott RandolphReturn<EvsResult> HalCamera::clientStreamStarting() { 130dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph Return<EvsResult> result = EvsResult::OK; 131dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 132dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (mStreamState == STOPPED) { 133dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph result = mHwCamera->startVideoStream(this); 134dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 135dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 136dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return result; 137dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 138dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 139dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 140dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphvoid HalCamera::clientStreamEnding() { 141dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Do we still have a running client? 142dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph bool stillRunning = false; 14329803803b299652fc219713774181dd9a7dd8decScott Randolph for (auto&& client : mClients) { 14429803803b299652fc219713774181dd9a7dd8decScott Randolph sp<VirtualCamera> virtCam = client.promote(); 14529803803b299652fc219713774181dd9a7dd8decScott Randolph if (virtCam != nullptr) { 14629803803b299652fc219713774181dd9a7dd8decScott Randolph stillRunning |= virtCam->isStreaming(); 14729803803b299652fc219713774181dd9a7dd8decScott Randolph } 148dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 149dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 150dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // If not, then stop the hardware stream 151dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (!stillRunning) { 152dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mHwCamera->stopVideoStream(); 153dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 154dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 155dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 156dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 157dcc3534f0f7523e4ee7285522586d6e2827aa407Scott RandolphReturn<void> HalCamera::doneWithFrame(const BufferDesc& buffer) { 158dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Find this frame in our list of outstanding frames 159dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph unsigned i; 160dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph for (i=0; i<mFrames.size(); i++) { 161dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (mFrames[i].frameId == buffer.bufferId) { 162dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph break; 163dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 164dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 165dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (i == mFrames.size()) { 166dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGE("We got a frame back with an ID we don't recognize!"); 167dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } else { 168dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Are there still clients using this buffer? 169dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mFrames[i].refCount--; 170dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (mFrames[i].refCount <= 0) { 171dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Since all our clients are done with this buffer, return it to the device layer 172dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mHwCamera->doneWithFrame(buffer); 173dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 174dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 175dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 176dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return Void(); 177dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 178dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 179dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 180dcc3534f0f7523e4ee7285522586d6e2827aa407Scott RandolphReturn<void> HalCamera::deliverFrame(const BufferDesc& buffer) { 181dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Run through all our clients and deliver this frame to any who are eligible 182dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph unsigned frameDeliveries = 0; 183dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph for (auto&& client : mClients) { 18429803803b299652fc219713774181dd9a7dd8decScott Randolph sp<VirtualCamera> virtCam = client.promote(); 18529803803b299652fc219713774181dd9a7dd8decScott Randolph if (virtCam != nullptr) { 18629803803b299652fc219713774181dd9a7dd8decScott Randolph if (virtCam->deliverFrame(buffer)) { 18729803803b299652fc219713774181dd9a7dd8decScott Randolph frameDeliveries++; 18829803803b299652fc219713774181dd9a7dd8decScott Randolph } 189dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 190dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 191dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 192dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (frameDeliveries < 1) { 193dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // If none of our clients could accept the frame, then return it right away 194dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGI("Trivially rejecting frame with no acceptances"); 195dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mHwCamera->doneWithFrame(buffer); 196dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } else { 197dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Add an entry for this frame in our tracking list 198dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph unsigned i; 199dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph for (i=0; i<mFrames.size(); i++) { 200dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (mFrames[i].refCount == 0) { 201dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph break; 202dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 203dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 204dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (i == mFrames.size()) { 205dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mFrames.emplace_back(buffer.bufferId); 206dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } else { 20729803803b299652fc219713774181dd9a7dd8decScott Randolph mFrames[i].frameId = buffer.bufferId; 208dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 209dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mFrames[i].refCount = frameDeliveries; 210dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 211dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 212dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return Void(); 213dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 214dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 215dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace implementation 216dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace V1_0 217dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace evs 218dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace automotive 219dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace android 220