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 38 ISVBuffer::~ISVBuffer() { 39 if (mWorker != NULL) { 40 ALOGV("%s: mSurface %d", __func__, mSurface); 41 mWorker->freeSurface(&mSurface); 42 } 43 } 44 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 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 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 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 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 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 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 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