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