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