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 <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