1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_SERVERS_CAMERA_CAMERA3_PREVIEWFRAMESPACER_H 18 #define ANDROID_SERVERS_CAMERA_CAMERA3_PREVIEWFRAMESPACER_H 19 20 #include <queue> 21 22 #include <gui/Surface.h> 23 #include <utils/Condition.h> 24 #include <utils/Mutex.h> 25 #include <utils/Thread.h> 26 #include <utils/Timers.h> 27 28 namespace android { 29 30 namespace camera3 { 31 32 class Camera3OutputStream; 33 34 /*** 35 * Preview stream spacer for better frame spacing 36 * 37 * The ideal viewfinder user experience is that frames are presented to the 38 * user in the same cadence as outputed by the camera sensor. However, the 39 * processing latency between frames could vary, due to factors such 40 * as CPU load, differences in request settings, etc. This frame processing 41 * latency results in variation in presentation of frames to the user. 42 * 43 * The PreviewFrameSpacer improves the viewfinder user experience by: 44 * - Cache the frame buffers if the intervals between queueBuffer is shorter 45 * than the camera readout intervals. 46 * - Queue frame buffers in the same cadence as the camera readout time. 47 * - Maintain at most 1 queue-able buffer. If the 2nd preview buffer becomes 48 * available, queue the oldest cached buffer to the buffer queue. 49 */ 50 class PreviewFrameSpacer : public Thread { 51 public: 52 explicit PreviewFrameSpacer(wp<Camera3OutputStream> parent, sp<Surface> consumer); 53 virtual ~PreviewFrameSpacer(); 54 55 // Queue preview buffer locally 56 status_t queuePreviewBuffer(nsecs_t timestamp, nsecs_t readoutTimestamp, 57 int32_t transform, ANativeWindowBuffer* anwBuffer, int releaseFence); 58 59 bool threadLoop() override; 60 void requestExit() override; 61 status_t run(const char* name, int32_t priority = PRIORITY_DEFAULT, size_t stack = 0) override; 62 63 private: 64 // structure holding cached preview buffer info 65 struct BufferHolder { 66 nsecs_t timestamp; 67 nsecs_t readoutTimestamp; 68 int32_t transform; 69 sp<ANativeWindowBuffer> anwBuffer; 70 int releaseFence; 71 BufferHolderBufferHolder72 BufferHolder(nsecs_t t, nsecs_t readoutT, int32_t tr, ANativeWindowBuffer* anwb, int rf) : 73 timestamp(t), readoutTimestamp(readoutT), transform(tr), anwBuffer(anwb), 74 releaseFence(rf) {} 75 }; 76 77 void queueBufferToClientLocked(const BufferHolder& bufferHolder, nsecs_t currentTime); 78 79 wp<Camera3OutputStream> mParent; 80 sp<ANativeWindow> mConsumer; 81 mutable Mutex mLock; 82 Condition mBufferCond; 83 84 std::queue<BufferHolder> mPendingBuffers; 85 nsecs_t mLastCameraReadoutTime = 0; 86 nsecs_t mLastCameraPresentTime = 0; 87 static constexpr nsecs_t kWaitDuration = 5000000LL; // 50ms 88 static constexpr nsecs_t kFrameIntervalThreshold = 80000000LL; // 80ms 89 static constexpr nsecs_t kMaxFrameWaitTime = 10000000LL; // 10ms 90 static constexpr nsecs_t kFrameAdjustThreshold = 2000000LL; // 2ms 91 }; 92 93 }; //namespace camera3 94 }; //namespace android 95 96 #endif 97