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