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