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