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