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