1 /*
2  * Copyright (C) 2013 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 #include <stdio.h>
18 #include <hardware/camera3.h>
19 #include <hardware/gralloc.h>
20 #include <system/graphics.h>
21 #include <utils/Mutex.h>
22 
23 //#define LOG_NDEBUG 0
24 #define LOG_TAG "Stream"
25 #include <cutils/log.h>
26 
27 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
28 #include <utils/Trace.h>
29 
30 #include "Stream.h"
31 
32 namespace default_camera_hal {
33 
Stream(int id,camera3_stream_t * s)34 Stream::Stream(int id, camera3_stream_t *s)
35   : mReuse(false),
36     mId(id),
37     mStream(s),
38     mType(s->stream_type),
39     mWidth(s->width),
40     mHeight(s->height),
41     mFormat(s->format),
42     mUsage(0),
43     mMaxBuffers(0),
44     mRegistered(false),
45     mBuffers(0),
46     mNumBuffers(0)
47 {
48 }
49 
~Stream()50 Stream::~Stream()
51 {
52     android::Mutex::Autolock al(mLock);
53     unregisterBuffers_L();
54 }
55 
setUsage(uint32_t usage)56 void Stream::setUsage(uint32_t usage)
57 {
58     android::Mutex::Autolock al(mLock);
59     if (usage != mUsage) {
60         mUsage = usage;
61         mStream->usage = usage;
62         unregisterBuffers_L();
63     }
64 }
65 
setMaxBuffers(uint32_t max_buffers)66 void Stream::setMaxBuffers(uint32_t max_buffers)
67 {
68     android::Mutex::Autolock al(mLock);
69     if (max_buffers != mMaxBuffers) {
70         mMaxBuffers = max_buffers;
71         mStream->max_buffers = max_buffers;
72         unregisterBuffers_L();
73     }
74 }
75 
getType()76 int Stream::getType()
77 {
78     return mType;
79 }
80 
isInputType()81 bool Stream::isInputType()
82 {
83     return mType == CAMERA3_STREAM_INPUT ||
84         mType == CAMERA3_STREAM_BIDIRECTIONAL;
85 }
86 
isOutputType()87 bool Stream::isOutputType()
88 {
89     return mType == CAMERA3_STREAM_OUTPUT ||
90         mType == CAMERA3_STREAM_BIDIRECTIONAL;
91 }
92 
typeToString(int type)93 const char* Stream::typeToString(int type)
94 {
95     switch (type) {
96     case CAMERA3_STREAM_INPUT:
97         return "CAMERA3_STREAM_INPUT";
98     case CAMERA3_STREAM_OUTPUT:
99         return "CAMERA3_STREAM_OUTPUT";
100     case CAMERA3_STREAM_BIDIRECTIONAL:
101         return "CAMERA3_STREAM_BIDIRECTIONAL";
102     }
103     return "Invalid stream type!";
104 }
105 
formatToString(int format)106 const char* Stream::formatToString(int format)
107 {
108     // See <system/graphics.h> for full list
109     switch (format) {
110     case HAL_PIXEL_FORMAT_BGRA_8888:
111         return "BGRA 8888";
112     case HAL_PIXEL_FORMAT_RGBA_8888:
113         return "RGBA 8888";
114     case HAL_PIXEL_FORMAT_RGBX_8888:
115         return "RGBX 8888";
116     case HAL_PIXEL_FORMAT_RGB_888:
117         return "RGB 888";
118     case HAL_PIXEL_FORMAT_RGB_565:
119         return "RGB 565";
120     case HAL_PIXEL_FORMAT_sRGB_A_8888:
121         return "sRGB A 8888";
122     case HAL_PIXEL_FORMAT_sRGB_X_8888:
123         return "sRGB B 8888";
124     case HAL_PIXEL_FORMAT_Y8:
125         return "Y8";
126     case HAL_PIXEL_FORMAT_Y16:
127         return "Y16";
128     case HAL_PIXEL_FORMAT_YV12:
129         return "YV12";
130     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
131         return "NV16";
132     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
133         return "NV21";
134     case HAL_PIXEL_FORMAT_YCbCr_422_I:
135         return "YUY2";
136     case HAL_PIXEL_FORMAT_RAW_SENSOR:
137         return "RAW SENSOR";
138     case HAL_PIXEL_FORMAT_BLOB:
139         return "BLOB";
140     case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
141         return "IMPLEMENTATION DEFINED";
142     case HAL_PIXEL_FORMAT_YCbCr_420_888:
143         return "FLEXIBLE YCbCr 420 888";
144     }
145     return "Invalid stream format!";
146 }
147 
isRegistered()148 bool Stream::isRegistered()
149 {
150     return mRegistered;
151 }
152 
isValidReuseStream(int id,camera3_stream_t * s)153 bool Stream::isValidReuseStream(int id, camera3_stream_t *s)
154 {
155     if (id != mId) {
156         ALOGE("%s:%d: Invalid camera id for reuse. Got %d expect %d",
157                 __func__, mId, id, mId);
158         return false;
159     }
160     if (s != mStream) {
161         ALOGE("%s:%d: Invalid stream handle for reuse. Got %p expect %p",
162                 __func__, mId, s, mStream);
163         return false;
164     }
165     if (s->stream_type != mType) {
166         ALOGE("%s:%d: Mismatched type in reused stream. Got %s(%d) "
167                 "expect %s(%d)", __func__, mId, typeToString(s->stream_type),
168                 s->stream_type, typeToString(mType), mType);
169         return false;
170     }
171     if (s->format != mFormat) {
172         ALOGE("%s:%d: Mismatched format in reused stream. Got %s(%d) "
173                 "expect %s(%d)", __func__, mId, formatToString(s->format),
174                 s->format, formatToString(mFormat), mFormat);
175         return false;
176     }
177     if (s->width != mWidth) {
178         ALOGE("%s:%d: Mismatched width in reused stream. Got %d expect %d",
179                 __func__, mId, s->width, mWidth);
180         return false;
181     }
182     if (s->height != mHeight) {
183         ALOGE("%s:%d: Mismatched height in reused stream. Got %d expect %d",
184                 __func__, mId, s->height, mHeight);
185         return false;
186     }
187     return true;
188 }
189 
registerBuffers(const camera3_stream_buffer_set_t * buf_set)190 int Stream::registerBuffers(const camera3_stream_buffer_set_t *buf_set)
191 {
192     ATRACE_CALL();
193     android::Mutex::Autolock al(mLock);
194 
195     if (buf_set->stream != mStream) {
196         ALOGE("%s:%d: Buffer set for invalid stream. Got %p expect %p",
197                 __func__, mId, buf_set->stream, mStream);
198         return -EINVAL;
199     }
200 
201     mNumBuffers = buf_set->num_buffers;
202     mBuffers = new buffer_handle_t*[mNumBuffers];
203 
204     for (unsigned int i = 0; i < mNumBuffers; i++) {
205         ALOGV("%s:%d: Registering buffer %p", __func__, mId,
206                 buf_set->buffers[i]);
207         mBuffers[i] = buf_set->buffers[i];
208         // TODO: register buffers with hw, handle error cases
209     }
210     mRegistered = true;
211 
212     return 0;
213 }
214 
215 // This must only be called with mLock held
unregisterBuffers_L()216 void Stream::unregisterBuffers_L()
217 {
218     mRegistered = false;
219     mNumBuffers = 0;
220     delete [] mBuffers;
221     // TODO: unregister buffers from hw
222 }
223 
dump(int fd)224 void Stream::dump(int fd)
225 {
226     android::Mutex::Autolock al(mLock);
227 
228     dprintf(fd, "Stream ID: %d (%p)\n", mId, mStream);
229     dprintf(fd, "Stream Type: %s (%d)\n", typeToString(mType), mType);
230     dprintf(fd, "Width: %"PRIu32" Height: %"PRIu32"\n", mWidth, mHeight);
231     dprintf(fd, "Stream Format: %s (%d)", formatToString(mFormat), mFormat);
232     // ToDo: prettyprint usage mask flags
233     dprintf(fd, "Gralloc Usage Mask: %#"PRIx32"\n", mUsage);
234     dprintf(fd, "Max Buffer Count: %"PRIu32"\n", mMaxBuffers);
235     dprintf(fd, "Buffers Registered: %s\n", mRegistered ? "true" : "false");
236     dprintf(fd, "Number of Buffers: %"PRIu32"\n", mNumBuffers);
237     for (uint32_t i = 0; i < mNumBuffers; i++) {
238         dprintf(fd, "Buffer %"PRIu32"/%"PRIu32": %p\n", i, mNumBuffers,
239                 mBuffers[i]);
240     }
241 }
242 
243 } // namespace default_camera_hal
244