blob: c0574fd3d4da07ae79908ad91060ecde6740cc63 [file] [log] [blame]
Shuzhen Wange4adddb2021-09-21 15:24:44 -07001/*
2 * Copyright (C) 2021 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_PREVIEWFRAMESCHEDULER_H
18#define ANDROID_SERVERS_CAMERA_CAMERA3_PREVIEWFRAMESCHEDULER_H
19
20#include <queue>
21
22#include <android/choreographer.h>
23#include <gui/Surface.h>
24#include <gui/ISurfaceComposer.h>
25#include <utils/Condition.h>
26#include <utils/Mutex.h>
27#include <utils/Looper.h>
28#include <utils/Thread.h>
29#include <utils/Timers.h>
30
31namespace android {
32
33namespace camera3 {
34
35class Camera3OutputStream;
36struct ChoreographerThread;
37
38/***
39 * Preview stream scheduler for better preview display synchronization
40 *
41 * The ideal viewfinder user experience is that frames are presented to the
42 * user in the same cadence as outputed by the camera sensor. However, the
43 * processing latency between frames could vary, due to factors such
44 * as CPU load, differences in request settings, etc. This frame processing
45 * latency results in variation in presentation of frames to the user.
46 *
47 * The PreviewFrameScheduler improves the viewfinder user experience by:
48 * 1. Cache preview buffers in the scheduler
49 * 2. For each choreographer callback, queue the oldest cached buffer with
50 * the best matching presentation timestamp. Frame N's presentation timestamp
51 * is the choreographer timeline timestamp closest to (Frame N-1's
52 * presentation time + camera capture interval between frame N-1 and frame N).
53 * 3. Maintain at most 2 queue-able buffers. If the 3rd preview buffer becomes
54 * available, queue the oldest cached buffer to the buffer queue.
55 */
56class PreviewFrameScheduler {
57 public:
58 explicit PreviewFrameScheduler(Camera3OutputStream& parent, sp<Surface> consumer);
59 virtual ~PreviewFrameScheduler();
60
61 // Queue preview buffer locally
62 status_t queuePreviewBuffer(nsecs_t timestamp, int32_t transform,
63 ANativeWindowBuffer* anwBuffer, int releaseFence);
64
65 // Callback function with a new presentation timeline from choreographer. This
66 // will trigger a locally queued buffer be sent to the buffer queue.
67 void onNewPresentationTime(const std::vector<nsecs_t>& presentationTimeline);
68
69 // Maintain at most 2 queue-able buffers
70 static constexpr int32_t kQueueDepthWatermark = 2;
71
72 private:
73 // structure holding cached preview buffer info
74 struct BufferHolder {
75 nsecs_t timestamp;
76 int32_t transform;
77 sp<ANativeWindowBuffer> anwBuffer;
78 int releaseFence;
79
80 BufferHolder(nsecs_t t, int32_t tr, ANativeWindowBuffer* anwb, int rf) :
81 timestamp(t), transform(tr), anwBuffer(anwb), releaseFence(rf) {}
82 };
83
84 status_t queueBufferToClientLocked(const BufferHolder& bufferHolder,
85 nsecs_t presentTime);
86
87 static constexpr char kPendingBufferTraceName[] = "pending_preview_buffers";
88
89 // Camera capture interval for resetting frame spacing between preview sessions
90 static constexpr nsecs_t kSpacingResetIntervalNs = 1000000000L; // 1 second
91
92 Camera3OutputStream& mParent;
93 sp<ANativeWindow> mConsumer;
94 mutable Mutex mLock;
95
96 std::queue<BufferHolder> mPendingBuffers;
97 nsecs_t mLastCameraCaptureTime = 0;
98 nsecs_t mLastCameraPresentTime = 0;
99
100 // Choreographer related
101 sp<Looper> mLooper;
102 sp<ChoreographerThread> mChoreographerThread;
103};
104
105}; //namespace camera3
106}; //namespace android
107
108#endif