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 62 private: 63 // structure holding cached preview buffer info 64 struct BufferHolder { 65 nsecs_t timestamp; 66 nsecs_t readoutTimestamp; 67 int32_t transform; 68 sp<ANativeWindowBuffer> anwBuffer; 69 int releaseFence; 70 BufferHolderBufferHolder71 BufferHolder(nsecs_t t, nsecs_t readoutT, int32_t tr, ANativeWindowBuffer* anwb, int rf) : 72 timestamp(t), readoutTimestamp(readoutT), transform(tr), anwBuffer(anwb), 73 releaseFence(rf) {} 74 }; 75 76 void queueBufferToClientLocked(const BufferHolder& bufferHolder, nsecs_t currentTime); 77 78 wp<Camera3OutputStream> mParent; 79 sp<ANativeWindow> mConsumer; 80 mutable Mutex mLock; 81 Condition mBufferCond; 82 83 std::queue<BufferHolder> mPendingBuffers; 84 nsecs_t mLastCameraReadoutTime = 0; 85 nsecs_t mLastCameraPresentTime = 0; 86 static constexpr nsecs_t kWaitDuration = 5000000LL; // 50ms 87 static constexpr nsecs_t kFrameIntervalThreshold = 80000000LL; // 80ms 88 static constexpr nsecs_t kMaxFrameWaitTime = 10000000LL; // 10ms 89 static constexpr nsecs_t kFrameAdjustThreshold = 2000000LL; // 2ms 90 }; 91 92 }; //namespace camera3 93 }; //namespace android 94 95 #endif 96