1/*
2 * Copyright (C) 2015 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
17package com.android.camera.one.v2.camera2proxy;
18
19import android.graphics.ImageFormat;
20import android.media.Image;
21import android.os.Handler;
22import android.view.Surface;
23
24import com.google.common.base.Objects;
25
26import javax.annotation.Nonnull;
27import javax.annotation.Nullable;
28import javax.annotation.concurrent.GuardedBy;
29
30/**
31 * A replacement for {@link android.media.ImageReader}.
32 */
33public final class AndroidImageReaderProxy implements ImageReaderProxy {
34    private final Object mLock;
35    @GuardedBy("mLock")
36    private final android.media.ImageReader mDelegate;
37
38    public AndroidImageReaderProxy(android.media.ImageReader delegate) {
39        mLock = new Object();
40        mDelegate = delegate;
41    }
42
43    /**
44     * @See {@link android.media.ImageReader}
45     */
46    public static ImageReaderProxy newInstance(int width, int height, int format, int maxImages) {
47        return new AndroidImageReaderProxy(android.media.ImageReader.newInstance(width, height,
48                format, maxImages));
49    }
50
51    private static String imageFormatToString(int imageFormat) {
52        switch (imageFormat) {
53            case ImageFormat.JPEG:
54                return "JPEG";
55            case ImageFormat.NV16:
56                return "NV16";
57            case ImageFormat.NV21:
58                return "NV21";
59            case ImageFormat.RAW10:
60                return "RAW10";
61            case ImageFormat.RAW_SENSOR:
62                return "RAW_SENSOR";
63            case ImageFormat.RGB_565:
64                return "RGB_565";
65            case ImageFormat.UNKNOWN:
66                return "UNKNOWN";
67            case ImageFormat.YUV_420_888:
68                return "YUV_420_888";
69            case ImageFormat.YUY2:
70                return "YUY2";
71            case ImageFormat.YV12:
72                return "YV12";
73        }
74        return Integer.toString(imageFormat);
75    }
76
77    @Override
78    public int getWidth() {
79        synchronized (mLock) {
80            return mDelegate.getWidth();
81        }
82    }
83
84    @Override
85    public int getHeight() {
86        synchronized (mLock) {
87            return mDelegate.getHeight();
88        }
89    }
90
91    @Override
92    public int getImageFormat() {
93        synchronized (mLock) {
94            return mDelegate.getImageFormat();
95        }
96    }
97
98    @Override
99    public int getMaxImages() {
100        synchronized (mLock) {
101            return mDelegate.getMaxImages();
102        }
103    }
104
105    @Override
106    @Nonnull
107    public Surface getSurface() {
108        synchronized (mLock) {
109            return mDelegate.getSurface();
110        }
111    }
112
113    @Override
114    @Nullable
115    public ImageProxy acquireLatestImage() {
116        synchronized (mLock) {
117            Image image = mDelegate.acquireLatestImage();
118            if (image == null) {
119                return null;
120            } else {
121                return new AndroidImageProxy(image);
122            }
123        }
124    }
125
126    @Override
127    @Nullable
128    public ImageProxy acquireNextImage() {
129        synchronized (mLock) {
130            Image image = mDelegate.acquireNextImage();
131            if (image == null) {
132                return null;
133            } else {
134                return new AndroidImageProxy(image);
135            }
136        }
137    }
138
139    @Override
140    public void setOnImageAvailableListener(@Nonnull
141    final ImageReaderProxy.OnImageAvailableListener listener,
142            Handler handler) {
143        synchronized (mLock) {
144            mDelegate.setOnImageAvailableListener(
145                    new android.media.ImageReader.OnImageAvailableListener() {
146                        @Override
147                        public void onImageAvailable(android.media.ImageReader imageReader) {
148                            listener.onImageAvailable();
149                        }
150                    }, handler);
151        }
152    }
153
154    @Override
155    public void close() {
156        synchronized (mLock) {
157            mDelegate.close();
158        }
159    }
160
161    @Override
162    public String toString() {
163        Objects.ToStringHelper tsh;
164        synchronized (mLock) {
165            tsh = Objects.toStringHelper(mDelegate);
166        }
167        return tsh.add("width", getWidth())
168                .add("height", getHeight())
169                .add("format", imageFormatToString(getImageFormat()))
170                .toString();
171    }
172}
173