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
17//#define LOG_NDEBUG 0
18#define LOG_TAG "Stream"
19
20#include <stdio.h>
21
22#include <log/log.h>
23#include <utils/Mutex.h>
24
25#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
26#include <utils/Trace.h>
27
28#include <hardware/camera3.h>
29#include <hardware/gralloc.h>
30#include <system/graphics.h>
31
32#include "Stream.h"
33
34namespace usb_camera_hal {
35
36Stream::Stream(int id, camera3_stream_t *s)
37  : mReuse(false),
38    mId(id),
39    mStream(s){
40}
41
42Stream::~Stream() {
43    for (size_t i = 0; i < mBuffers.size(); i++) {
44        delete mBuffers[i];
45    }
46
47    mBuffers.clear();
48}
49
50void Stream::setUsage(uint32_t usage) {
51    android::Mutex::Autolock al(mLock);
52    if (usage != mStream->usage) {
53        mStream->usage = usage;
54    }
55}
56
57void Stream::setMaxBuffers(uint32_t max_buffers) {
58    android::Mutex::Autolock al(mLock);
59    if (max_buffers != mStream->max_buffers) {
60        mStream->max_buffers = max_buffers;
61    }
62}
63
64int Stream::getType() {
65    return mStream->stream_type;
66}
67
68bool Stream::isInputType() {
69    return mStream->stream_type == CAMERA3_STREAM_INPUT ||
70            mStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL;
71}
72
73bool Stream::isOutputType() {
74    return mStream->stream_type == CAMERA3_STREAM_OUTPUT ||
75            mStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL;
76}
77
78const char* Stream::typeToString(int type) {
79    switch (type) {
80    case CAMERA3_STREAM_INPUT:
81        return "CAMERA3_STREAM_INPUT";
82    case CAMERA3_STREAM_OUTPUT:
83        return "CAMERA3_STREAM_OUTPUT";
84    case CAMERA3_STREAM_BIDIRECTIONAL:
85        return "CAMERA3_STREAM_BIDIRECTIONAL";
86    }
87    return "Invalid stream type!";
88}
89
90const char* Stream::formatToString(int format) {
91    // See <system/graphics.h> for full list
92    switch (format) {
93    case HAL_PIXEL_FORMAT_BGRA_8888:
94        return "BGRA 8888";
95    case HAL_PIXEL_FORMAT_RGBA_8888:
96        return "RGBA 8888";
97    case HAL_PIXEL_FORMAT_RGBX_8888:
98        return "RGBX 8888";
99    case HAL_PIXEL_FORMAT_RGB_888:
100        return "RGB 888";
101    case HAL_PIXEL_FORMAT_RGB_565:
102        return "RGB 565";
103    case HAL_PIXEL_FORMAT_Y8:
104        return "Y8";
105    case HAL_PIXEL_FORMAT_Y16:
106        return "Y16";
107    case HAL_PIXEL_FORMAT_YV12:
108        return "YV12";
109    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
110        return "NV16";
111    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
112        return "NV21";
113    case HAL_PIXEL_FORMAT_YCbCr_422_I:
114        return "YUY2";
115    case HAL_PIXEL_FORMAT_RAW10:
116        return "RAW10";
117    case HAL_PIXEL_FORMAT_RAW16:
118        return "RAW16";
119    case HAL_PIXEL_FORMAT_BLOB:
120        return "BLOB";
121    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
122        return "IMPLEMENTATION DEFINED";
123    case HAL_PIXEL_FORMAT_YCbCr_420_888:
124        return "FLEXIBLE YCbCr 420 888";
125    }
126    return "Invalid stream format!";
127}
128
129bool Stream::isValidReuseStream(int id, camera3_stream_t *s) {
130    if (id != mId) {
131        ALOGE("%s:%d: Invalid camera id for reuse. Got %d expect %d",
132                __func__, mId, id, mId);
133        return false;
134    }
135    if (s != mStream) {
136        ALOGE("%s:%d: Invalid stream handle for reuse. Got %p expect %p",
137                __func__, mId, s, mStream);
138        return false;
139    }
140    if (s->stream_type != mStream->stream_type) {
141        ALOGE("%s:%d: Mismatched type in reused stream. Got %s(%d) "
142                "expect %s(%d)", __func__, mId, typeToString(s->stream_type),
143                s->stream_type, typeToString(mStream->stream_type), mStream->stream_type);
144        return false;
145    }
146    if (s->format != mStream->format) {
147        ALOGE("%s:%d: Mismatched format in reused stream. Got %s(%d) "
148                "expect %s(%d)", __func__, mId, formatToString(s->format),
149                s->format, formatToString(mStream->format), mStream->format);
150        return false;
151    }
152    if (s->width != mStream->width) {
153        ALOGE("%s:%d: Mismatched width in reused stream. Got %d expect %d",
154                __func__, mId, s->width, mStream->width);
155        return false;
156    }
157    if (s->height != mStream->height) {
158        ALOGE("%s:%d: Mismatched height in reused stream. Got %d expect %d",
159                __func__, mId, s->height, mStream->height);
160        return false;
161    }
162    return true;
163}
164
165void Stream::dump(int fd) {
166    android::Mutex::Autolock al(mLock);
167
168    dprintf(fd, "Stream ID: %d (%p)\n", mId, mStream);
169    dprintf(fd, "Stream Type: %s (%d)\n", typeToString(mStream->stream_type), mStream->stream_type);
170    dprintf(fd, "Width: %" PRIu32 " Height: %" PRIu32 "\n", mStream->width, mStream->height);
171    dprintf(fd, "Stream Format: %s (%d)", formatToString(mStream->format), mStream->format);
172    // ToDo: prettyprint usage mask flags
173    dprintf(fd, "Gralloc Usage Mask: %#" PRIx32 "\n", mStream->usage);
174    dprintf(fd, "Max Buffer Count: %" PRIu32 "\n", mStream->max_buffers);
175    dprintf(fd, "Number of Buffers in use by HAL: %zu\n", mBuffers.size());
176    for (size_t i = 0; i < mBuffers.size(); i++) {
177        dprintf(fd, "Buffer %zu/%zu: %p\n", i, mBuffers.size(), mBuffers[i]);
178    }
179}
180
181} // namespace usb_camera_hal
182