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

Commit 4dd110ae authored by Eino-Ville Talvala's avatar Eino-Ville Talvala Committed by Android Git Automerger
Browse files

am 254446a8: Camera2/3: Move recording frame processing to its own thread.

* commit '254446a8':
  Camera2/3: Move recording frame processing to its own thread.
parents cbbd6c83 254446a8
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -102,6 +102,9 @@ status_t Camera2Client::initialize(camera_module_t *module)
    String8 threadName;

    mStreamingProcessor = new StreamingProcessor(this);
    threadName = String8::format("C2-%d-StreamProc",
            mCameraId);
    mStreamingProcessor->run(threadName.string());

    mFrameProcessor = new FrameProcessor(mDevice, this);
    threadName = String8::format("C2-%d-FrameProc",
@@ -411,6 +414,7 @@ void Camera2Client::disconnect() {
    mCallbackProcessor->deleteStream();
    mZslProcessor->deleteStream();

    mStreamingProcessor->requestExit();
    mFrameProcessor->requestExit();
    mCaptureSequencer->requestExit();
    mJpegProcessor->requestExit();
@@ -419,6 +423,7 @@ void Camera2Client::disconnect() {

    ALOGV("Camera %d: Waiting for threads", mCameraId);

    mStreamingProcessor->join();
    mFrameProcessor->join();
    mCaptureSequencer->join();
    mJpegProcessor->join();
+46 −11
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
        mPreviewStreamId(NO_STREAM),
        mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
        mRecordingStreamId(NO_STREAM),
        mRecordingFrameAvailable(false),
        mRecordingHeapCount(kDefaultRecordingHeapCount)
{
}
@@ -535,6 +536,36 @@ status_t StreamingProcessor::incrementStreamingIds() {
}

void StreamingProcessor::onFrameAvailable() {
    ATRACE_CALL();
    Mutex::Autolock l(mMutex);
    if (!mRecordingFrameAvailable) {
        mRecordingFrameAvailable = true;
        mRecordingFrameAvailableSignal.signal();
    }

}

bool StreamingProcessor::threadLoop() {
    status_t res;

    {
        Mutex::Autolock l(mMutex);
        while (!mRecordingFrameAvailable) {
            res = mRecordingFrameAvailableSignal.waitRelative(
                mMutex, kWaitDuration);
            if (res == TIMED_OUT) return true;
        }
        mRecordingFrameAvailable = false;
    }

    do {
        res = processRecordingFrame();
    } while (res == OK);

    return true;
}

status_t StreamingProcessor::processRecordingFrame() {
    ATRACE_CALL();
    status_t res;
    sp<Camera2Heap> recordingHeap;
@@ -547,12 +578,14 @@ void StreamingProcessor::onFrameAvailable() {
        BufferItemConsumer::BufferItem imgBuffer;
        res = mRecordingConsumer->acquireBuffer(&imgBuffer);
        if (res != OK) {
            ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
            if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
                ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
                        __FUNCTION__, mId, strerror(-res), res);
            return;
            }
            return res;
        }
        mRecordingConsumer->releaseBuffer(imgBuffer);
        return;
        return OK;
    }

    {
@@ -563,23 +596,24 @@ void StreamingProcessor::onFrameAvailable() {
        BufferItemConsumer::BufferItem imgBuffer;
        res = mRecordingConsumer->acquireBuffer(&imgBuffer);
        if (res != OK) {
            ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
            if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
                ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
                        __FUNCTION__, mId, strerror(-res), res);
            return;
            }
            return res;
        }
        timestamp = imgBuffer.mTimestamp;

        mRecordingFrameCount++;
        ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);

        // TODO: Signal errors here upstream
        if (l.mParameters.state != Parameters::RECORD &&
                l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
            ALOGV("%s: Camera %d: Discarding recording image buffers "
                    "received after recording done", __FUNCTION__,
                    mId);
            mRecordingConsumer->releaseBuffer(imgBuffer);
            return;
            return INVALID_OPERATION;
        }

        if (mRecordingHeap == 0) {
@@ -594,7 +628,7 @@ void StreamingProcessor::onFrameAvailable() {
                ALOGE("%s: Camera %d: Unable to allocate memory for recording",
                        __FUNCTION__, mId);
                mRecordingConsumer->releaseBuffer(imgBuffer);
                return;
                return NO_MEMORY;
            }
            for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
                if (mRecordingBuffers[i].mBuf !=
@@ -615,7 +649,7 @@ void StreamingProcessor::onFrameAvailable() {
            ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
                    __FUNCTION__, mId);
            mRecordingConsumer->releaseBuffer(imgBuffer);
            return;
            return NO_MEMORY;
        }

        heapIdx = mRecordingHeapHead;
@@ -649,6 +683,7 @@ void StreamingProcessor::onFrameAvailable() {
                CAMERA_MSG_VIDEO_FRAME,
                recordingHeap->mBuffers[heapIdx]);
    }
    return OK;
}

void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) {
+10 −1
Original line number Diff line number Diff line
@@ -37,7 +37,8 @@ class Camera2Heap;
/**
 * Management and processing for preview and recording streams
 */
class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener {
class StreamingProcessor:
            public Thread, public BufferItemConsumer::FrameAvailableListener {
  public:
    StreamingProcessor(sp<Camera2Client> client);
    ~StreamingProcessor();
@@ -103,6 +104,8 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener {
    sp<ANativeWindow> mPreviewWindow;

    // Recording-related members
    static const nsecs_t kWaitDuration = 50000000; // 50 ms

    int32_t mRecordingRequestId;
    int mRecordingStreamId;
    int mRecordingFrameCount;
@@ -111,11 +114,17 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener {
    CameraMetadata mRecordingRequest;
    sp<camera2::Camera2Heap> mRecordingHeap;

    bool mRecordingFrameAvailable;
    Condition mRecordingFrameAvailableSignal;

    static const size_t kDefaultRecordingHeapCount = 8;
    size_t mRecordingHeapCount;
    Vector<BufferItemConsumer::BufferItem> mRecordingBuffers;
    size_t mRecordingHeapHead, mRecordingHeapFree;

    virtual bool threadLoop();

    status_t processRecordingFrame();
};