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