1feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/* 2feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Copyright (C) 2014 The Android Open Source Project 3feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 4feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * you may not use this file except in compliance with the License. 6feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * You may obtain a copy of the License at 7feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 8feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 10feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Unless required by applicable law or agreed to in writing, software 11feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * See the License for the specific language governing permissions and 14feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * limitations under the License. 15feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 16feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpackage android.hardware.camera2.legacy; 17feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 18feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.CaptureRequest; 19feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.LongParcelable; 20feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.Log; 21feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.Pair; 22feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.ArrayDeque; 24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.List; 25feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 26feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * A queue of bursts of requests. 28feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 29feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p>This queue maintains the count of frames that have been produced, and is thread safe.</p> 30feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 31feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpublic class RequestQueue { 32feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final String TAG = "RequestQueue"; 33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 34feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final long INVALID_FRAME = -1; 35feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 36feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private BurstHolder mRepeatingRequest = null; 37feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final ArrayDeque<BurstHolder> mRequestQueue = new ArrayDeque<BurstHolder>(); 38feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 39feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private long mCurrentFrameNumber = 0; 40feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private long mCurrentRepeatingFrameNumber = INVALID_FRAME; 41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private int mCurrentRequestId = 0; 420fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk private final List<Long> mJpegSurfaceIds; 43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 440fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk public RequestQueue(List<Long> jpegSurfaceIds) { 450fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk mJpegSurfaceIds = jpegSurfaceIds; 460fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk } 47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 49feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Return and remove the next burst on the queue. 50feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p>If a repeating burst is returned, it will not be removed.</p> 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @return a pair containing the next burst and the current frame number, or null if none exist. 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public synchronized Pair<BurstHolder, Long> getNext() { 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk BurstHolder next = mRequestQueue.poll(); 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (next == null && mRepeatingRequest != null) { 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk next = mRepeatingRequest; 59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mCurrentRepeatingFrameNumber = mCurrentFrameNumber + 60feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk next.getNumberOfRequests(); 61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 62feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 63feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (next == null) { 64feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return null; 65feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 66feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Pair<BurstHolder, Long> ret = new Pair<BurstHolder, Long>(next, mCurrentFrameNumber); 68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mCurrentFrameNumber += next.getNumberOfRequests(); 69feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return ret; 70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 71feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 72feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Cancel a repeating request. 74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param requestId the id of the repeating request to cancel. 76feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @return the last frame to be returned from the HAL for the given repeating request, or 77feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@code INVALID_FRAME} if none exists. 78feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 79feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public synchronized long stopRepeating(int requestId) { 80feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk long ret = INVALID_FRAME; 81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mRepeatingRequest != null && mRepeatingRequest.getRequestId() == requestId) { 82feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mRepeatingRequest = null; 8353284d5816f065b2de20dcb019fa1096b148eee4Ruben Brunk ret = (mCurrentRepeatingFrameNumber == INVALID_FRAME) ? INVALID_FRAME : 8453284d5816f065b2de20dcb019fa1096b148eee4Ruben Brunk mCurrentRepeatingFrameNumber - 1; 85feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mCurrentRepeatingFrameNumber = INVALID_FRAME; 86e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.i(TAG, "Repeating capture request cancelled."); 87feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 88feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "cancel failed: no repeating request exists for request id: " + requestId); 89feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 90feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return ret; 91feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 92feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /** 94e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk * Cancel a repeating request. 95e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk * 96e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk * @return the last frame to be returned from the HAL for the given repeating request, or 97e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk * {@code INVALID_FRAME} if none exists. 98e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk */ 99e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk public synchronized long stopRepeating() { 100e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mRepeatingRequest == null) { 101e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "cancel failed: no repeating request exists."); 102e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return INVALID_FRAME; 103e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 104e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return stopRepeating(mRepeatingRequest.getRequestId()); 105e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 106e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 107e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk /** 108feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Add a the given burst to the queue. 109feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 110feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p>If the burst is repeating, replace the current repeating burst.</p> 111feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 112feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param requests the burst of requests to add to the queue. 113feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param repeating true if the burst is repeating. 114feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @param frameNumber an output argument that contains either the frame number of the last frame 115feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * that will be returned for this request, or the frame number of the last 116feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * frame that will be returned for the current repeating request if this 117feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * burst is set to be repeating. 118feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * @return the request id. 119feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 120feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public synchronized int submit(List<CaptureRequest> requests, boolean repeating, 121feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /*out*/LongParcelable frameNumber) { 122feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int requestId = mCurrentRequestId++; 1230fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk BurstHolder burst = new BurstHolder(requestId, repeating, requests, mJpegSurfaceIds); 124feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk long ret = INVALID_FRAME; 125feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (burst.isRepeating()) { 126e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.i(TAG, "Repeating capture request set."); 127feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mRepeatingRequest != null) { 12853284d5816f065b2de20dcb019fa1096b148eee4Ruben Brunk ret = (mCurrentRepeatingFrameNumber == INVALID_FRAME) ? INVALID_FRAME : 12953284d5816f065b2de20dcb019fa1096b148eee4Ruben Brunk mCurrentRepeatingFrameNumber - 1; 130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mCurrentRepeatingFrameNumber = INVALID_FRAME; 132feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mRepeatingRequest = burst; 133feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } else { 134feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mRequestQueue.offer(burst); 135feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ret = calculateLastFrame(burst.getRequestId()); 136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 137feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk frameNumber.setNumber(ret); 138feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return requestId; 139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 140feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 141feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private long calculateLastFrame(int requestId) { 142feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk long total = mCurrentFrameNumber; 143feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk for (BurstHolder b : mRequestQueue) { 144feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk total += b.getNumberOfRequests(); 145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (b.getRequestId() == requestId) { 14691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk return total - 1; 147feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk throw new IllegalStateException( 150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk "At least one request must be in the queue to calculate frame number"); 151feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 153feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 154