Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 983cf231 authored by James Dong's avatar James Dong
Browse files

Dynamically configure the number of video buffers used by camera source, if supported

o related-to-bug: 6920805

Change-Id: I413bb50954cc84e32ed40bcb713842dc7b58e2b6
parent 15d7245e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ protected:

    int32_t  mCameraFlags;
    Size     mVideoSize;
    int32_t  mNumInputBuffers;
    int32_t  mVideoFrameRate;
    int32_t  mColorFormat;
    status_t mInitCheck;
+25 −3
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ CameraSource::CameraSource(
    const sp<Surface>& surface,
    bool storeMetaDataInVideoBuffers)
    : mCameraFlags(0),
      mNumInputBuffers(0),
      mVideoFrameRate(-1),
      mCamera(0),
      mSurface(surface),
@@ -571,6 +572,18 @@ void CameraSource::startCameraRecording() {
    // camera and recording is started by the applications. The applications
    // will connect to the camera in ICameraRecordingProxy::startRecording.
    int64_t token = IPCThreadState::self()->clearCallingIdentity();
    if (mNumInputBuffers > 0) {
        status_t err = mCamera->sendCommand(
            CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0);

        // This could happen for CameraHAL1 clients; thus the failure is
        // not a fatal error
        if (err != OK) {
            ALOGW("Failed to set video buffer count to %d due to %d",
                mNumInputBuffers, err);
        }
    }

    if (mCameraFlags & FLAGS_HOT_CAMERA) {
        mCamera->unlock();
        mCamera.clear();
@@ -599,11 +612,20 @@ status_t CameraSource::start(MetaData *meta) {
    }

    mStartTimeUs = 0;
    mNumInputBuffers = 0;
    if (meta) {
        int64_t startTimeUs;
    if (meta && meta->findInt64(kKeyTime, &startTimeUs)) {
        if (meta->findInt64(kKeyTime, &startTimeUs)) {
            mStartTimeUs = startTimeUs;
        }

        int32_t nBuffers;
        if (meta->findInt32(kKeyNumBuffers, &nBuffers)) {
            CHECK_GT(nBuffers, 0);
            mNumInputBuffers = nBuffers;
        }
    }

    startCameraRecording();

    mStarted = true;
+32 −7
Original line number Diff line number Diff line
@@ -58,7 +58,8 @@ Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
        mCaptureStreamId(NO_STREAM),
        mCaptureRequest(NULL),
        mRecordingStreamId(NO_STREAM),
        mRecordingRequest(NULL)
        mRecordingRequest(NULL),
        mRecordingHeapCount(kDefaultRecordingHeapCount)
{
    ATRACE_CALL();

@@ -1544,6 +1545,30 @@ status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
        } else {
            return NO_INIT;
        }
    } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
        if (recordingEnabled()) {
            ALOGE("%s: Camera %d: Error setting video buffer count after "
                    "recording was started", __FUNCTION__, mCameraId);
            return INVALID_OPERATION;
        }

        // 32 is the current upper limit on the video buffer count for BufferQueue
        if (arg1 <= 0 || arg1 > 32) {
            ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
                    __FUNCTION__, mCameraId, arg1);
            return BAD_VALUE;
        }

        // Need to reallocate memory for heap
        if (mRecordingHeapCount != arg1) {
            if  (mRecordingHeap != 0) {
                mRecordingHeap.clear();
                mRecordingHeap = NULL;
            }
            mRecordingHeapCount = arg1;
        }

        return OK;
    }

    ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
@@ -1649,17 +1674,17 @@ void Camera2Client::onRecordingFrameAvailable() {
            const size_t bufferSize = 4 + sizeof(buffer_handle_t);
            ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
                    "size %d bytes", __FUNCTION__, mCameraId,
                    kRecordingHeapCount, bufferSize);
                    mRecordingHeapCount, bufferSize);
            if (mRecordingHeap != 0) {
                ALOGV("%s: Camera %d: Previous heap has size %d "
                        "(new will be %d) bytes", __FUNCTION__, mCameraId,
                        mRecordingHeap->mHeap->getSize(),
                        bufferSize * kRecordingHeapCount);
                        bufferSize * mRecordingHeapCount);
            }
            // Need to allocate memory for heap
            mRecordingHeap.clear();

            mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
            mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
                    "Camera2Client::RecordingHeap");
            if (mRecordingHeap->mHeap->getSize() == 0) {
                ALOGE("%s: Camera %d: Unable to allocate memory for recording",
@@ -1668,7 +1693,7 @@ void Camera2Client::onRecordingFrameAvailable() {
                return;
            }
            mRecordingHeapHead = 0;
            mRecordingHeapFree = kRecordingHeapCount;
            mRecordingHeapFree = mRecordingHeapCount;
        }

        if ( mRecordingHeapFree == 0) {
@@ -1678,7 +1703,7 @@ void Camera2Client::onRecordingFrameAvailable() {
            return;
        }
        heapIdx = mRecordingHeapHead;
        mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
        mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
        mRecordingHeapFree--;

        ALOGV("%s: Camera %d: Timestamp %lld",
@@ -2688,7 +2713,7 @@ status_t Camera2Client::updateRecordingStream(const Parameters &params) {

    if (mRecordingConsumer == 0) {
        // Create CPU buffer queue endpoint
        mRecordingConsumer = new MediaConsumer(kRecordingHeapCount);
        mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
        mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
        mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
        mRecordingWindow = new SurfaceTextureClient(
+2 −1
Original line number Diff line number Diff line
@@ -288,7 +288,8 @@ private:
    // TODO: This needs to be queried from somewhere, or the BufferQueue needs
    // to be passed all the way to stagefright. Right now, set to a large number
    // to avoid starvation of the video encoders.
    static const size_t kRecordingHeapCount = 8;
    static const size_t kDefaultRecordingHeapCount = 8;
    size_t mRecordingHeapCount;
    size_t mRecordingHeapHead, mRecordingHeapFree;
    // Handle new recording image buffers
    void onRecordingFrameAvailable();
+3 −0
Original line number Diff line number Diff line
@@ -619,6 +619,9 @@ status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
        return OK;
    } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
        mCameraService->playSound(CameraService::SOUND_RECORDING);
    } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
        // Silently ignore this command
        return INVALID_OPERATION;
    } else if (cmd == CAMERA_CMD_PING) {
        // If mHardware is 0, checkPidAndHardware will return error.
        return OK;