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