1 /*
2  * Copyright (C) 2014 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 package com.android.camera.one.v2.sharedimagereader;
18 
19 import android.view.Surface;
20 
21 import com.android.camera.async.BufferQueue;
22 import com.android.camera.async.BufferQueueController;
23 import com.android.camera.one.v2.camera2proxy.ImageProxy;
24 import com.android.camera.one.v2.core.ResourceAcquisitionFailedException;
25 import com.android.camera.one.v2.sharedimagereader.imagedistributor.ImageDistributor;
26 import com.android.camera.one.v2.sharedimagereader.ticketpool.ReservableTicketPool;
27 import com.android.camera.one.v2.sharedimagereader.ticketpool.TicketPool;
28 
29 import java.util.concurrent.atomic.AtomicBoolean;
30 
31 /**
32  * An ImageQueueCaptureStream with a fixed-capacity which can reserve space
33  * ahead of time via {@link #allocate}.
34  */
35 class AllocatingImageStream extends ImageStreamImpl {
36     private final int mCapacity;
37     private final ReservableTicketPool mTicketPool;
38     /**
39      * True if capacity for the stream has has been allocated.
40      */
41     private AtomicBoolean mAllocated;
42     private AtomicBoolean mClosed;
43 
44     /**
45      * @param capacity The capacity to reserve on first bind.
46      * @param ticketPool The ticket pool to reserve capacity in. Note that this
47      *            class takes ownership of this ticket pool.
48      * @param imageStream The output to the images queue.
49      * @param imageStreamController The input to the image queue.
50      * @param imageDistributor The image distributor to register with on bind()
51      *            such that the image queue begins receiving images.
52      * @param surface
53      */
AllocatingImageStream( int capacity, ReservableTicketPool ticketPool, BufferQueue<ImageProxy> imageStream, BufferQueueController<ImageProxy> imageStreamController, ImageDistributor imageDistributor, Surface surface)54     public AllocatingImageStream(
55             int capacity, ReservableTicketPool ticketPool,
56             BufferQueue<ImageProxy> imageStream,
57             BufferQueueController<ImageProxy> imageStreamController,
58             ImageDistributor imageDistributor, Surface surface) {
59         super(imageStream, imageStreamController, imageDistributor, surface);
60         mCapacity = capacity;
61         mTicketPool = ticketPool;
62         mAllocated = new AtomicBoolean(false);
63         mClosed = new AtomicBoolean(false);
64     }
65 
allocate()66     public void allocate() throws InterruptedException, ResourceAcquisitionFailedException {
67         if (!mAllocated.getAndSet(true)) {
68             try {
69                 mTicketPool.reserveCapacity(mCapacity);
70             } catch (TicketPool.NoCapacityAvailableException e) {
71                 throw new ResourceAcquisitionFailedException(e);
72             }
73         }
74     }
75 
76     @Override
bind(BufferQueue<Long> timestamps)77     public Surface bind(BufferQueue<Long> timestamps) throws InterruptedException,
78             ResourceAcquisitionFailedException {
79         allocate();
80         return super.bind(timestamps);
81     }
82 
83     @Override
close()84     public void close() {
85         if (mClosed.getAndSet(true)) {
86             return;
87         }
88         mTicketPool.close();
89         super.close();
90     }
91 }
92