1 /*
2 * Copyright (C) 2012 Intel Corporation. All rights reserved.
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
18 #include <inttypes.h>
19
20 #include <media/hardware/HardwareAPI.h>
21 #include <system/graphics.h>
22 #include "isv_bufmanager.h"
23 #ifndef TARGET_VPP_USE_GEN
24 #include "hal_public.h"
25 #endif
26
27 //#define LOG_NDEBUG 0
28 #undef LOG_TAG
29 #define LOG_TAG "isv-omxil"
30
31 using namespace android;
32
33 #define GRALLOC_SUB_BUFFER_MAX 3
34 #define RANDOM_BUFFER_SIZE 200
35 static char random_buf[RANDOM_BUFFER_SIZE];
36
~ISVBuffer()37 ISVBuffer::~ISVBuffer() {
38 if (mWorker != NULL) {
39 ALOGV("%s: mSurface %d", __func__, mSurface);
40 mWorker->freeSurface(&mSurface);
41 }
42 }
43
initBufferInfo(uint32_t hackFormat)44 status_t ISVBuffer::initBufferInfo(uint32_t hackFormat)
45 {
46 if (mType == ISV_BUFFER_METADATA) {
47 VideoDecoderOutputMetaData *metaData =
48 reinterpret_cast<VideoDecoderOutputMetaData*>(mBuffer);
49
50 if (metaData->eType != kMetadataBufferTypeGrallocSource) {
51 ALOGE("%s: unsupported meta data format eType = %d", __func__, metaData->eType);
52 return UNKNOWN_ERROR;
53 }
54
55 if (mGrallocHandle != 0) {
56 if ((unsigned long)metaData->pHandle != mGrallocHandle) {
57 if (STATUS_OK != mWorker->freeSurface(&mSurface)) {
58 ALOGE("%s: free surface %d failed.", __func__, mSurface);
59 return UNKNOWN_ERROR;
60 }
61 } else
62 return OK;
63 }
64 mGrallocHandle = (unsigned long)metaData->pHandle;
65 } else {
66 if (mSurface != -1)
67 return OK;
68 mGrallocHandle = mBuffer;
69 }
70
71 int32_t err = 0;
72 if (!mpGralloc) {
73 err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (hw_module_t const**)&mpGralloc);
74 if (0 != err)
75 return UNKNOWN_ERROR;
76 }
77 #ifdef TARGET_VPP_USE_GEN
78 ufo_buffer_details_t info;
79
80 memset(&info, 0, sizeof(ufo_buffer_details_t));
81 err = mpGralloc->perform(mpGralloc, INTEL_UFO_GRALLOC_MODULE_PERFORM_GET_BO_INFO, mGrallocHandle, &info);
82
83 if (0 != err) {
84 ALOGE("%s: can't get graphic buffer info", __func__);
85 }
86 mWidth = info.width;
87 mHeight = info.height;
88 mStride = info.pitch;
89 mColorFormat = info.format;
90 #else
91 IMG_native_handle_t* grallocHandle = (IMG_native_handle_t*)mGrallocHandle;
92 mStride = grallocHandle->aiStride[0];
93 mSurfaceHeight = grallocHandle->iHeight;
94 mColorFormat = (hackFormat != 0) ? hackFormat : grallocHandle->iFormat;
95 #endif
96 if (mWorker == NULL) {
97 ALOGE("%s: mWorker == NULL!!", __func__);
98 return UNKNOWN_ERROR;
99 }
100
101 if (STATUS_OK != mWorker->allocSurface(&mWidth, &mHeight, mStride, mColorFormat, mGrallocHandle, &mSurface)) {
102 ALOGE("%s: alloc surface failed, mGrallocHandle %lu", __func__, mGrallocHandle);
103 return UNKNOWN_ERROR;
104 }
105
106 ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG,
107 "%s: mWidth %d, mHeight %d, mStride %d, mColorFormat %d, "
108 "mGrallocHandle %p, mSurface %d",
109 __func__, mWidth, mHeight, mStride, mColorFormat,
110 reinterpret_cast<void*>(mGrallocHandle), mSurface);
111 return OK;
112 }
113
clearIfNeed()114 status_t ISVBuffer::clearIfNeed()
115 {
116 #ifndef TARGET_VPP_USE_GEN
117 static bool bRandomBufferInit = false;
118 if (!bRandomBufferInit) {
119 time_t my_time;
120 srand((unsigned)time(&my_time));
121 for (int32_t i = 0; i < RANDOM_BUFFER_SIZE; i++)
122 random_buf[i] = (char)(((double)rand()/(double)RAND_MAX) * 255.0);
123 bRandomBufferInit = true;
124 }
125
126 if ((mFlags & ISV_BUFFER_NEED_CLEAR) && mpGralloc) {
127 int32_t usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
128 void *vaddr[GRALLOC_SUB_BUFFER_MAX];
129
130 int32_t err = mpGralloc->lock(mpGralloc, (buffer_handle_t)mGrallocHandle, usage, 0, 0, mStride, mSurfaceHeight, &vaddr[0]);
131
132 if (0 != err) {
133 ALOGE("%s: get graphic buffer ptr failed", __func__);
134 return UNKNOWN_ERROR;
135 }
136
137 int32_t buffer_size = mStride * mSurfaceHeight * 3 / 2;
138 char* ptr = (char*)vaddr[0];
139 for (int32_t i = 0; i < buffer_size/RANDOM_BUFFER_SIZE; i++) {
140 memcpy(ptr, random_buf, sizeof(random_buf));
141 ptr += sizeof(random_buf);
142 }
143 mpGralloc->unlock(mpGralloc, (buffer_handle_t)mGrallocHandle);
144 ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: clear isv buffer %p finished, buffer size %d", __func__, this, buffer_size);
145 mFlags &= ~ISV_BUFFER_NEED_CLEAR;
146 }
147 #endif
148 return OK;
149 }
150
setBufferCount(int32_t size)151 status_t ISVBufferManager::setBufferCount(int32_t size)
152 {
153 Mutex::Autolock autoLock(mBufferLock);
154 #if 0
155 if (!mBuffers.isEmpty()) {
156 ALOGE("%s: the buffer queue should be empty before we set its size", __func__);
157 return STATUS_ERROR;
158 }
159 #endif
160 mBuffers.setCapacity(size);
161
162 return OK;
163 }
164
freeBuffer(unsigned long handle)165 status_t ISVBufferManager::freeBuffer(unsigned long handle)
166 {
167 Mutex::Autolock autoLock(mBufferLock);
168 for (uint32_t i = 0; i < mBuffers.size(); i++) {
169 ISVBuffer* isvBuffer = mBuffers.itemAt(i);
170 if (isvBuffer->getHandle() == handle) {
171 delete isvBuffer;
172 mBuffers.removeAt(i);
173 ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: remove handle 0x%08lx, and then mBuffers.size() %d", __func__,
174 handle, mBuffers.size());
175 return OK;
176 }
177 }
178
179 ALOGW("%s: can't find buffer %lu", __func__, handle);
180 return UNKNOWN_ERROR;
181 }
182
useBuffer(unsigned long handle)183 status_t ISVBufferManager::useBuffer(unsigned long handle)
184 {
185 Mutex::Autolock autoLock(mBufferLock);
186 if (handle == 0 || mBuffers.size() >= mBuffers.capacity())
187 return BAD_VALUE;
188
189 for (uint32_t i = 0; i < mBuffers.size(); i++) {
190 ISVBuffer* isvBuffer = mBuffers.itemAt(i);
191 if (isvBuffer->getHandle() == handle) {
192 ALOGE("%s: this buffer 0x%08lx has already been registered", __func__, handle);
193 return UNKNOWN_ERROR;
194 }
195 }
196
197 ISVBuffer* isvBuffer = new ISVBuffer(mWorker, handle,
198 mMetaDataMode ? ISVBuffer::ISV_BUFFER_METADATA : ISVBuffer::ISV_BUFFER_GRALLOC,
199 mNeedClearBuffers ? ISVBuffer::ISV_BUFFER_NEED_CLEAR : 0);
200
201 ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG,
202 "%s: add handle 0x%08lx, and then mBuffers.size() %d", __func__,
203 handle, mBuffers.size());
204 mBuffers.push_back(isvBuffer);
205 return OK;
206
207 }
208
useBuffer(const sp<ANativeWindowBuffer> nativeBuffer)209 status_t ISVBufferManager::useBuffer(const sp<ANativeWindowBuffer> nativeBuffer)
210 {
211 Mutex::Autolock autoLock(mBufferLock);
212 if (nativeBuffer == NULL || mBuffers.size() >= mBuffers.capacity())
213 return BAD_VALUE;
214
215 for (uint32_t i = 0; i < mBuffers.size(); i++) {
216 ISVBuffer* isvBuffer = mBuffers.itemAt(i);
217 if (isvBuffer->getHandle() == (unsigned long)nativeBuffer->handle) {
218 ALOGE(
219 "%s: this buffer 0x%08" PRIxPTR " has already been registered",
220 __func__, reinterpret_cast<uintptr_t>(nativeBuffer->handle));
221 return UNKNOWN_ERROR;
222 }
223 }
224
225 ISVBuffer* isvBuffer = new ISVBuffer(mWorker,
226 (unsigned long)nativeBuffer->handle, (unsigned long)nativeBuffer->handle,
227 nativeBuffer->width, nativeBuffer->height,
228 nativeBuffer->stride, nativeBuffer->format,
229 mMetaDataMode ? ISVBuffer::ISV_BUFFER_METADATA : ISVBuffer::ISV_BUFFER_GRALLOC,
230 mNeedClearBuffers ? ISVBuffer::ISV_BUFFER_NEED_CLEAR : 0);
231
232 ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG,
233 "%s: add handle 0x%08" PRIxPTR ", and then mBuffers.size() %d",
234 __func__, reinterpret_cast<uintptr_t>(nativeBuffer->handle),
235 mBuffers.size());
236 mBuffers.push_back(isvBuffer);
237 return OK;
238 }
239
mapBuffer(unsigned long handle)240 ISVBuffer* ISVBufferManager::mapBuffer(unsigned long handle)
241 {
242 Mutex::Autolock autoLock(mBufferLock);
243 for (uint32_t i = 0; i < mBuffers.size(); i++) {
244 ISVBuffer* isvBuffer = mBuffers.itemAt(i);
245 if (isvBuffer->getHandle() == handle)
246 return isvBuffer;
247 }
248 return NULL;
249 }
250
setBuffersFlag(uint32_t flag)251 status_t ISVBufferManager::setBuffersFlag(uint32_t flag)
252 {
253 Mutex::Autolock autoLock(mBufferLock);
254
255 if (flag & ISVBuffer::ISV_BUFFER_NEED_CLEAR) {
256 if (mBuffers.size() == 0)
257 mNeedClearBuffers = true;
258 else {
259 for (uint32_t i = 0; i < mBuffers.size(); i++) {
260 ISVBuffer* isvBuffer = mBuffers.itemAt(i);
261 isvBuffer->setFlag(ISVBuffer::ISV_BUFFER_NEED_CLEAR);
262 }
263 }
264 }
265 return OK;
266 }
267