173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala/*
273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project
373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala *
473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala * you may not use this file except in compliance with the License.
673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala * You may obtain a copy of the License at
773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala *
873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala *
1073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
1173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
1273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala * See the License for the specific language governing permissions and
1473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala * limitations under the License.
1573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala */
1673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
1773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#define LOG_TAG "Camera2-StreamingProcessor"
1873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
1973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala//#define LOG_NDEBUG 0
2073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
2173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include <utils/Log.h>
2273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include <utils/Trace.h>
2373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include <gui/SurfaceTextureClient.h>
2473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include <media/hardware/MetadataBufferType.h>
2573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
2673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include "StreamingProcessor.h"
2773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include "Camera2Heap.h"
2873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include "../Camera2Client.h"
2973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include "../Camera2Device.h"
3073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
3173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalanamespace android {
3273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalanamespace camera2 {
3373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
3473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville TalvalaStreamingProcessor::StreamingProcessor(wp<Camera2Client> client):
3573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mClient(client),
364865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        mActiveRequest(NONE),
374865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        mPreviewRequestId(Camera2Client::kPreviewRequestIdStart),
3873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mPreviewStreamId(NO_STREAM),
394865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
4073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingStreamId(NO_STREAM),
4173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingHeapCount(kDefaultRecordingHeapCount)
4273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala{
4373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
4473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
4573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
4673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville TalvalaStreamingProcessor::~StreamingProcessor() {
4773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    deletePreviewStream();
4873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    deleteRecordingStream();
4973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
5073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
5173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::setPreviewWindow(sp<ANativeWindow> window) {
5273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
5373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
5473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
5573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = deletePreviewStream();
5673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (res != OK) return res;
5773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
5873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
5973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
6073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    mPreviewWindow = window;
6173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
6273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
6373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
6473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
6573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalabool StreamingProcessor::haveValidPreviewWindow() const {
6673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
6773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return mPreviewWindow != 0;
6873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
6973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
7073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::updatePreviewRequest(const Parameters &params) {
7173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
7273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
7373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
7473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (client == 0) return INVALID_OPERATION;
7573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
7673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
7773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mPreviewRequest.entryCount() == 0) {
7873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = client->getCameraDevice()->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
7973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                &mPreviewRequest);
8073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
8173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Camera %d: Unable to create default preview request: "
8273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res);
8373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
8473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
8573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
8673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
8773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = params.updateRequest(&mPreviewRequest);
8873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (res != OK) {
8973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Unable to update common entries of preview "
9073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                "request: %s (%d)", __FUNCTION__, client->getCameraId(),
9173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                strerror(-res), res);
9273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return res;
9373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
9473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
9573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = mPreviewRequest.update(ANDROID_REQUEST_ID,
964865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala            &mPreviewRequestId, 1);
974865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    if (res != OK) {
984865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)",
994865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala                __FUNCTION__, client->getCameraId(), strerror(-res), res);
1004865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        return res;
1014865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    }
10273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
10373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
10473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
10573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
10673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::updatePreviewStream(const Parameters &params) {
10773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
10873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
10973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
11073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
11173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
11273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (client == 0) return INVALID_OPERATION;
11373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Device> device = client->getCameraDevice();
11473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
11573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mPreviewStreamId != NO_STREAM) {
11673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        // Check if stream parameters have to change
11773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        uint32_t currentWidth, currentHeight;
11873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = device->getStreamInfo(mPreviewStreamId,
11973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                &currentWidth, &currentHeight, 0);
12073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
12173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Camera %d: Error querying preview stream info: "
12273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res);
12373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
12473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
12573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (currentWidth != (uint32_t)params.previewWidth ||
12673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                currentHeight != (uint32_t)params.previewHeight) {
12773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
12873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    __FUNCTION__, client->getCameraId(), currentWidth, currentHeight,
12973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    params.previewWidth, params.previewHeight);
13073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            res = device->waitUntilDrained();
13173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            if (res != OK) {
13273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                ALOGE("%s: Camera %d: Error waiting for preview to drain: "
13373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                        "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res);
13473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                return res;
13573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            }
13673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            res = device->deleteStream(mPreviewStreamId);
13773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            if (res != OK) {
13873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                ALOGE("%s: Camera %d: Unable to delete old output stream "
13973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                        "for preview: %s (%d)", __FUNCTION__, client->getCameraId(),
14073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                        strerror(-res), res);
14173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                return res;
14273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            }
14373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mPreviewStreamId = NO_STREAM;
14473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
14573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
14673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
14773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mPreviewStreamId == NO_STREAM) {
14873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = device->createStream(mPreviewWindow,
14973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                params.previewWidth, params.previewHeight,
15073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
15173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                &mPreviewStreamId);
15273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
15373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
15473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    __FUNCTION__, client->getCameraId(), strerror(-res), res);
15573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
15673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
15773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
15873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
15973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = device->setStreamTransform(mPreviewStreamId,
16073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            params.previewTransform);
16173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (res != OK) {
16273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Unable to set preview stream transform: "
16373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res);
16473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return res;
16573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
16673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
16773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
16873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
16973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
17073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::deletePreviewStream() {
17173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
17273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
17373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
17473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
17573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
17673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mPreviewStreamId != NO_STREAM) {
17773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
17873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (client == 0) return INVALID_OPERATION;
17973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        sp<Camera2Device> device = client->getCameraDevice();
18073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
181ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        ALOGV("%s: for cameraId %d on streamId %d",
182ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin            __FUNCTION__, client->getCameraId(), mPreviewStreamId);
183ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
18473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = device->waitUntilDrained();
18573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
18673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Error waiting for preview to drain: %s (%d)",
18773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    __FUNCTION__, strerror(-res), res);
18873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
18973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
19073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = device->deleteStream(mPreviewStreamId);
19173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
19273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Unable to delete old preview stream: %s (%d)",
19373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    __FUNCTION__, strerror(-res), res);
19473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
19573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
19673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mPreviewStreamId = NO_STREAM;
19773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
19873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
19973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
20073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
2014865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvalaint StreamingProcessor::getPreviewStreamId() const {
20273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
20373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return mPreviewStreamId;
20473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
20573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
20673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::setRecordingBufferCount(size_t count) {
20773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
20873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    // 32 is the current upper limit on the video buffer count for BufferQueue
20973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
21073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (client == 0) return INVALID_OPERATION;
21173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (count > 32) {
21273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
21373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                __FUNCTION__, client->getCameraId(), count);
21473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return BAD_VALUE;
21573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
21673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
21773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
21873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
21973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    // Need to reallocate memory for heap
22073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mRecordingHeapCount != count) {
22173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if  (mRecordingHeap != 0) {
22273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingHeap.clear();
22373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingHeap = NULL;
22473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
22573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingHeapCount = count;
22673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
22773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
22873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
22973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
23073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
23173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::updateRecordingRequest(const Parameters &params) {
23273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
23373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
23473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
23573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
23673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
23773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (client == 0) return INVALID_OPERATION;
23873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
23973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mRecordingRequest.entryCount() == 0) {
24073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = client->getCameraDevice()->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
24173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                &mRecordingRequest);
24273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
24373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Camera %d: Unable to create default recording request:"
24473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    " %s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res);
24573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
24673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
24773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
24873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
24973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = params.updateRequest(&mRecordingRequest);
25073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (res != OK) {
25173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Unable to update common entries of recording "
25273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                "request: %s (%d)", __FUNCTION__, client->getCameraId(),
25373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                strerror(-res), res);
25473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return res;
25573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
25673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
2574865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    res = mRecordingRequest.update(ANDROID_REQUEST_ID,
2584865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala            &mRecordingRequestId, 1);
2594865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    if (res != OK) {
2604865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)",
2614865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala                __FUNCTION__, client->getCameraId(), strerror(-res), res);
2624865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        return res;
2634865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    }
2644865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala
26573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
26673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
26773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
26873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
26973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
27073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
27173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
27273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
27373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
27473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (client == 0) return INVALID_OPERATION;
27573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Device> device = client->getCameraDevice();
27673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
27773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mRecordingConsumer == 0) {
27873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        // Create CPU buffer queue endpoint. We need one more buffer here so that we can
27973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        // always acquire and free a buffer when the heap is full; otherwise the consumer
28073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        // will have buffers in flight we'll never clear out.
28173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingConsumer = new BufferItemConsumer(
28273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                GRALLOC_USAGE_HW_VIDEO_ENCODER,
28373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                mRecordingHeapCount + 1,
28473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                true);
28573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingConsumer->setFrameAvailableListener(this);
28673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingConsumer->setName(String8("Camera2-RecordingConsumer"));
28773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingWindow = new SurfaceTextureClient(
28873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingConsumer->getProducerInterface());
28973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        // Allocate memory later, since we don't know buffer size until receipt
29073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
29173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
29273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mRecordingStreamId != NO_STREAM) {
29373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        // Check if stream parameters have to change
29473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        uint32_t currentWidth, currentHeight;
29573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = device->getStreamInfo(mRecordingStreamId,
29673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                &currentWidth, &currentHeight, 0);
29773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
29873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Camera %d: Error querying recording output stream info: "
29973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    "%s (%d)", __FUNCTION__, client->getCameraId(),
30073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    strerror(-res), res);
30173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
30273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
30373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (currentWidth != (uint32_t)params.videoWidth ||
30473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                currentHeight != (uint32_t)params.videoHeight) {
30573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            // TODO: Should wait to be sure previous recording has finished
30673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            res = device->deleteStream(mRecordingStreamId);
30773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            if (res != OK) {
30873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                ALOGE("%s: Camera %d: Unable to delete old output stream "
30973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                        "for recording: %s (%d)", __FUNCTION__,
31073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                        client->getCameraId(), strerror(-res), res);
31173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                return res;
31273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            }
31373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingStreamId = NO_STREAM;
31473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
31573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
31673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
31773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mRecordingStreamId == NO_STREAM) {
31873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingFrameCount = 0;
31973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = device->createStream(mRecordingWindow,
32073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                params.videoWidth, params.videoHeight,
32173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
32273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
32373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Camera %d: Can't create output stream for recording: "
32473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    "%s (%d)", __FUNCTION__, client->getCameraId(),
32573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    strerror(-res), res);
32673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
32773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
32873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
32973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
33073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
33173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
33273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
33373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::deleteRecordingStream() {
33473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
33573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
33673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
33773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
33873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
33973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mRecordingStreamId != NO_STREAM) {
34073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        sp<Camera2Client> client = mClient.promote();
34173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (client == 0) return INVALID_OPERATION;
34273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        sp<Camera2Device> device = client->getCameraDevice();
34373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
34473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = device->waitUntilDrained();
34573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
34673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
34773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    __FUNCTION__, strerror(-res), res);
34873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
34973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
35073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = device->deleteStream(mRecordingStreamId);
35173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
35273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Unable to delete recording stream: %s (%d)",
35373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    __FUNCTION__, strerror(-res), res);
35473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return res;
35573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
35673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingStreamId = NO_STREAM;
35773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
35873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
35973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
36073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
3614865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvalaint StreamingProcessor::getRecordingStreamId() const {
36273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return mRecordingStreamId;
36373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
36473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
36573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::startStream(StreamType type,
36673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        const Vector<uint8_t> &outputStreams) {
36773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
36873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
36973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
3704865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    if (type == NONE) return INVALID_OPERATION;
3714865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala
37273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
37373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (client == 0) return INVALID_OPERATION;
37473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
37522d58d37db6b5f48a10b3a19f69ffda09943c125Igor Murashkin    ALOGV("%s: Camera %d: type = %d", __FUNCTION__, client->getCameraId(), type);
37622d58d37db6b5f48a10b3a19f69ffda09943c125Igor Murashkin
37773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
37873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
37973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    CameraMetadata &request = (type == PREVIEW) ?
38073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mPreviewRequest : mRecordingRequest;
38173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
38273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = request.update(
38373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ANDROID_REQUEST_OUTPUT_STREAMS,
38473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        outputStreams);
38573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (res != OK) {
38673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
38773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                __FUNCTION__, client->getCameraId(), strerror(-res), res);
38873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return res;
38973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
39073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
39173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = request.sort();
39273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (res != OK) {
39373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
39473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                __FUNCTION__, client->getCameraId(), strerror(-res), res);
39573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return res;
39673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
39773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
39873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = client->getCameraDevice()->setStreamingRequest(request);
39973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (res != OK) {
40073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
40173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                "%s (%d)",
40273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                __FUNCTION__, client->getCameraId(), strerror(-res), res);
40373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return res;
40473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
4054865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    mActiveRequest = type;
40673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
40773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
40873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
40973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
41073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::stopStream() {
41173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
41273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
41373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
4144865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    Mutex::Autolock m(mMutex);
4154865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala
41673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
41773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (client == 0) return INVALID_OPERATION;
41873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Device> device = client->getCameraDevice();
41973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
42073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = device->clearStreamingRequest();
42173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (res != OK) {
42273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
42373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                __FUNCTION__, client->getCameraId(), strerror(-res), res);
42473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return res;
42573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
4264865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    mActiveRequest = NONE;
4274865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala
4284865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    return OK;
4294865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala}
4304865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala
4314865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvalaint32_t StreamingProcessor::getActiveRequestId() const {
4324865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    Mutex::Autolock m(mMutex);
4334865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    switch (mActiveRequest) {
4344865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        case NONE:
4354865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala            return 0;
4364865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        case PREVIEW:
4374865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala            return mPreviewRequestId;
4384865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        case RECORD:
4394865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala            return mRecordingRequestId;
4404865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        default:
4414865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala            ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest);
4424865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala            return 0;
4434865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    }
4444865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala}
4454865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala
4464865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvalastatus_t StreamingProcessor::incrementStreamingIds() {
4474865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    ATRACE_CALL();
4484865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    Mutex::Autolock m(mMutex);
4494865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala
4504865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    status_t res;
4514865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    mPreviewRequestId++;
4524865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
4534865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
4544865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    }
4554865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    mRecordingRequestId++;
4564865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala    if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) {
4574865c526e681366481b0ab242ffa1ead57bb02ccEino-Ville Talvala        mRecordingRequestId = Camera2Client::kRecordingRequestIdStart;
45873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
45973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
46073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
46173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
46273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalavoid StreamingProcessor::onFrameAvailable() {
46373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
46473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
46573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Heap> recordingHeap;
46673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    size_t heapIdx = 0;
46773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    nsecs_t timestamp;
46873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
46973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
47073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (client == 0) return;
47173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
47273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    {
47304273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin        /* acquire SharedParameters before mMutex so we don't dead lock
47404273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin            with Camera2Client code calling into StreamingProcessor */
47504273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin        SharedParameters::Lock l(client->getParameters());
47673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        Mutex::Autolock m(mMutex);
47773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        BufferItemConsumer::BufferItem imgBuffer;
47873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        res = mRecordingConsumer->acquireBuffer(&imgBuffer);
47973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (res != OK) {
48073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
48173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    __FUNCTION__, client->getCameraId(), strerror(-res), res);
48273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return;
48373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
48473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        timestamp = imgBuffer.mTimestamp;
48573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
48673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingFrameCount++;
48773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
48873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
48904273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin        // TODO: Signal errors here upstream
49004273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin        if (l.mParameters.state != Parameters::RECORD &&
49104273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin                l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
49204273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin            ALOGV("%s: Camera %d: Discarding recording image buffers "
49304273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin                    "received after recording done", __FUNCTION__,
49404273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin                    client->getCameraId());
49504273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin            mRecordingConsumer->releaseBuffer(imgBuffer);
49604273cb14d2326e85bb047ea6ef75294c8b3d561Igor Murashkin            return;
49773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
49873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
49973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (mRecordingHeap == 0) {
50073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            const size_t bufferSize = 4 + sizeof(buffer_handle_t);
50173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
50273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    "size %d bytes", __FUNCTION__, client->getCameraId(),
50373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    mRecordingHeapCount, bufferSize);
50473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
50573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
50673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    "Camera2Client::RecordingHeap");
50773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            if (mRecordingHeap->mHeap->getSize() == 0) {
50873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                ALOGE("%s: Camera %d: Unable to allocate memory for recording",
50973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                        __FUNCTION__, client->getCameraId());
51073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                mRecordingConsumer->releaseBuffer(imgBuffer);
51173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                return;
51273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            }
51373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
51473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                if (mRecordingBuffers[i].mBuf !=
51573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                        BufferItemConsumer::INVALID_BUFFER_SLOT) {
51673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    ALOGE("%s: Camera %d: Non-empty recording buffers list!",
51773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                            __FUNCTION__, client->getCameraId());
51873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                }
51973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            }
52073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingBuffers.clear();
52173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingBuffers.setCapacity(mRecordingHeapCount);
52273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingBuffers.insertAt(0, mRecordingHeapCount);
52373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
52473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingHeapHead = 0;
52573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingHeapFree = mRecordingHeapCount;
52673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
52773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
52873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if ( mRecordingHeapFree == 0) {
52973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
53073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                    __FUNCTION__, client->getCameraId());
53173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            mRecordingConsumer->releaseBuffer(imgBuffer);
53273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            return;
53373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
53473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
53573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        heapIdx = mRecordingHeapHead;
53673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
53773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingHeapFree--;
53873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
53973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGV("%s: Camera %d: Timestamp %lld",
54073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                __FUNCTION__, client->getCameraId(), timestamp);
54173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
54273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ssize_t offset;
54373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        size_t size;
54473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        sp<IMemoryHeap> heap =
54573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
54673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                        &size);
54773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
54873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        uint8_t *data = (uint8_t*)heap->getBase() + offset;
54973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        uint32_t type = kMetadataBufferTypeGrallocSource;
55073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        *((uint32_t*)data) = type;
55173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
55273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
55373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                __FUNCTION__, client->getCameraId(),
55473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                imgBuffer.mGraphicBuffer->handle);
55573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
55673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        recordingHeap = mRecordingHeap;
55773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
55873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
55973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    // Call outside locked parameters to allow re-entrancy from notification
56073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
56173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (l.mCameraClient != 0) {
56273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        l.mCameraClient->dataCallbackTimestamp(timestamp,
56373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                CAMERA_MSG_VIDEO_FRAME,
56473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                recordingHeap->mBuffers[heapIdx]);
56573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
56673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
56773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
56873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalavoid StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) {
56973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ATRACE_CALL();
57073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    status_t res;
57173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
57273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<Camera2Client> client = mClient.promote();
57373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (client == 0) return;
57473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
57573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    Mutex::Autolock m(mMutex);
57673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    // Make sure this is for the current heap
57773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ssize_t offset;
57873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    size_t size;
57973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
58073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
58173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
58273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                "(got %x, expected %x)", __FUNCTION__, client->getCameraId(),
58373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
58473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return;
58573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
58673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    uint8_t *data = (uint8_t*)heap->getBase() + offset;
58773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    uint32_t type = *(uint32_t*)data;
58873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (type != kMetadataBufferTypeGrallocSource) {
58973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
59073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                __FUNCTION__, client->getCameraId(), type,
59173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                kMetadataBufferTypeGrallocSource);
59273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return;
59373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
59473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
59573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    // Release the buffer back to the recording queue
59673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
59773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
59873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
59973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    size_t itemIndex;
60073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
60173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        const BufferItemConsumer::BufferItem item =
60273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                mRecordingBuffers[itemIndex];
60373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
60473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                item.mGraphicBuffer->handle == imgHandle) {
60573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            break;
60673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        }
60773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
60873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (itemIndex == mRecordingBuffers.size()) {
60973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
61073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                "outstanding buffers", __FUNCTION__, client->getCameraId(),
61173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                imgHandle);
61273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return;
61373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
61473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
61573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__,
61673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala            client->getCameraId(), imgHandle);
61773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
61873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
61973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (res != OK) {
62073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        ALOGE("%s: Camera %d: Unable to free recording frame "
62173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                "(buffer_handle_t: %p): %s (%d)", __FUNCTION__,
62273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala                client->getCameraId(), imgHandle, strerror(-res), res);
62373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        return;
62473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
62573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    mRecordingBuffers.replaceAt(itemIndex);
62673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
62773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    mRecordingHeapFree++;
62873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
62973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
63073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
63173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvalastatus_t StreamingProcessor::dump(int fd, const Vector<String16>& args) {
63273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    String8 result;
63373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
63473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    result.append("  Current requests:\n");
63573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mPreviewRequest.entryCount() != 0) {
63673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        result.append("    Preview request:\n");
63773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        write(fd, result.string(), result.size());
63873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mPreviewRequest.dump(fd, 2, 6);
63973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    } else {
64073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        result.append("    Preview request: undefined\n");
64173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        write(fd, result.string(), result.size());
64273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
64373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
64473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    if (mRecordingRequest.entryCount() != 0) {
64573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        result = "    Recording request:\n";
64673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        write(fd, result.string(), result.size());
64773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        mRecordingRequest.dump(fd, 2, 6);
64873bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    } else {
64973bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        result = "    Recording request: undefined\n";
65073bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala        write(fd, result.string(), result.size());
65173bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    }
65273bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
65373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala    return OK;
65473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}
65573bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala
65673bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}; // namespace camera2
65773bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala}; // namespace android
658