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