2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.camera.burst;
19 import androidx.collection.LongSparseArray;
21 import com.android.camera.async.SafeCloseable;
22 import com.android.camera.one.v2.camera2proxy.ImageProxy;
24 import java.util.ArrayList;
25 import java.util.List;
28 * A RingBuffer that is used during burst capture. It takes a
29 * {@link EvictionHandler} instance and uses it to evict frames when the ring
30 * buffer runs out of capacity.
32 class RingBuffer<T extends ImageProxy> implements SafeCloseable {
33 private final int mMaxCapacity;
34 private final EvictionHandler mEvictionHandler;
35 private final LongSparseArray<T> mImages = new LongSparseArray<>();
38 * Create a new ring buffer instance.
40 * @param maxCapacity the maximum number of images in the ring buffer.
41 * @param evictionHandler
43 public RingBuffer(int maxCapacity, EvictionHandler evictionHandler) {
44 mMaxCapacity = maxCapacity;
45 mEvictionHandler = evictionHandler;
49 * Insert an image in the ring buffer, evicting any frames if necessary.
51 * @param image the image to be inserted.
53 public synchronized void insertImage(T image) {
54 long timestamp = image.getTimestamp();
55 if (mImages.get(timestamp) != null) {
59 // Add image to ring buffer so it can be closed in case eviction
62 mEvictionHandler.onFrameInserted(timestamp);
63 if (mImages.size() > mMaxCapacity) {
64 long selectFrameToDrop = mEvictionHandler.selectFrameToDrop();
65 removeAndCloseImage(selectFrameToDrop);
66 mEvictionHandler.onFrameDropped(selectFrameToDrop);
71 * Returns all images present in the ring buffer.
73 public synchronized List<T> getAndRemoveAllImages() {
74 List<T> allImages = new ArrayList<>(mImages.size());
75 for (int i = 0; i < mImages.size(); i++) {
76 allImages.add(mImages.valueAt(i));
83 * Closes the ring buffer and any images in the ring buffer.
86 public synchronized void close() {
87 for (int i = 0; i < mImages.size(); i++) {
88 mImages.valueAt(i).close();
93 private synchronized void removeAndCloseImage(long timestampNs) {
94 mImages.get(timestampNs).close();
95 mImages.remove(timestampNs);
98 private synchronized void addImage(T image) {
99 mImages.put(image.getTimestamp(), image);