Home | History | Annotate | Download | only in base
      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