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 #include <sync/sync.h>
     26 #endif
     27 
     28 //#define LOG_NDEBUG 0
     29 #undef LOG_TAG
     30 #define LOG_TAG "isv-omxil"
     31 
     32 using namespace android;
     33 
     34 #define GRALLOC_SUB_BUFFER_MAX  3
     35 #define RANDOM_BUFFER_SIZE      200
     36 static char random_buf[RANDOM_BUFFER_SIZE];
     37 
     38 ISVBuffer::~ISVBuffer() {
     39     if (mWorker != NULL) {
     40         ALOGV("%s: mSurface %d", __func__, mSurface);
     41         mWorker->freeSurface(&mSurface);
     42     }
     43 }
     44 
     45 status_t ISVBuffer::initBufferInfo(uint32_t hackFormat)
     46 {
     47     if (mType == ISV_BUFFER_METADATA) {
     48         VideoDecoderOutputMetaData *metaData =
     49             reinterpret_cast<VideoDecoderOutputMetaData*>(mBuffer);
     50 
     51         if (metaData->eType != kMetadataBufferTypeGrallocSource) {
     52             ALOGE("%s: unsupported meta data format eType = %d", __func__, metaData->eType);
     53             return UNKNOWN_ERROR;
     54         }
     55 
     56         if (mGrallocHandle != 0) {
     57             if ((unsigned long)metaData->pHandle != mGrallocHandle) {
     58                 if (STATUS_OK != mWorker->freeSurface(&mSurface)) {
     59                     ALOGE("%s: free surface %d failed.", __func__, mSurface);
     60                     return UNKNOWN_ERROR;
     61                 }
     62             } else
     63                 return OK;
     64         }
     65         mGrallocHandle = (unsigned long)metaData->pHandle;
     66     } else {
     67         if (mSurface != -1)
     68             return OK;
     69         mGrallocHandle = mBuffer;
     70     }
     71 
     72     int32_t err = 0;
     73 #ifdef TARGET_VPP_USE_GEN
     74     if (!mpGralloc) {
     75         err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (hw_module_t const**)&mpGralloc);
     76         if (0 != err)
     77             return UNKNOWN_ERROR;
     78     }
     79     ufo_buffer_details_t info;
     80 
     81     memset(&info, 0, sizeof(ufo_buffer_details_t));
     82     err = mpGralloc->perform(mpGralloc, INTEL_UFO_GRALLOC_MODULE_PERFORM_GET_BO_INFO, mGrallocHandle, &info);
     83 
     84     if (0 != err) {
     85         ALOGE("%s: can't get graphic buffer info", __func__);
     86     }
     87     mWidth = info.width;
     88     mHeight = info.height;
     89     mStride = info.pitch;
     90     mColorFormat = info.format;
     91 #else
     92     if (!mpGralloc) {
     93         err = gralloc_open_img(&mpGralloc);
     94         if (0 != err)
     95             return UNKNOWN_ERROR;
     96     }
     97     IMG_native_handle_t* grallocHandle = (IMG_native_handle_t*)mGrallocHandle;
     98     mStride = grallocHandle->aiStride[0];
     99     mSurfaceHeight = grallocHandle->iHeight;
    100     mColorFormat = (hackFormat != 0) ? hackFormat : grallocHandle->iFormat;
    101 #endif
    102     if (mWorker == NULL) {
    103         ALOGE("%s: mWorker == NULL!!", __func__);
    104         return UNKNOWN_ERROR;
    105     }
    106 
    107     if (STATUS_OK != mWorker->allocSurface(&mWidth, &mHeight, mStride, mColorFormat, mGrallocHandle, &mSurface)) {
    108         ALOGE("%s: alloc surface failed, mGrallocHandle %lu", __func__, mGrallocHandle);
    109         return UNKNOWN_ERROR;
    110     }
    111 
    112     ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG,
    113              "%s: mWidth %d, mHeight %d, mStride %d, mColorFormat %d, "
    114              "mGrallocHandle %p, mSurface %d",
    115             __func__, mWidth, mHeight, mStride, mColorFormat,
    116             reinterpret_cast<void*>(mGrallocHandle), mSurface);
    117     return OK;
    118 }
    119 
    120 status_t ISVBuffer::clearIfNeed()
    121 {
    122 #ifndef TARGET_VPP_USE_GEN
    123     static bool bRandomBufferInit = false;
    124     if (!bRandomBufferInit) {
    125         time_t my_time;
    126         srand((unsigned)time(&my_time));
    127         for (int32_t i = 0; i < RANDOM_BUFFER_SIZE; i++)
    128             random_buf[i] = (char)(((double)rand()/(double)RAND_MAX) * 255.0);
    129         bRandomBufferInit = true;
    130     }
    131 
    132     if ((mFlags & ISV_BUFFER_NEED_CLEAR) && mpGralloc) {
    133         int32_t usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
    134         void *vaddr[GRALLOC_SUB_BUFFER_MAX];
    135         const gralloc1_rect_t r = {
    136             .width  = (int32_t)mStride,
    137             .height = (int32_t)mSurfaceHeight
    138         };
    139         int err, releaseFence = -1;
    140 
    141         err = gralloc_lock_async_img(mpGralloc, (buffer_handle_t)mGrallocHandle, usage, &r, &vaddr[0], -1);
    142         if (0 != err) {
    143             ALOGE("%s: get graphic buffer ptr failed", __func__);
    144             return UNKNOWN_ERROR;
    145         }
    146 
    147         int32_t buffer_size = mStride * mSurfaceHeight * 3 / 2;
    148         char* ptr = (char*)vaddr[0];
    149         for (int32_t i = 0; i < buffer_size/RANDOM_BUFFER_SIZE; i++) {
    150             memcpy(ptr, random_buf, sizeof(random_buf));
    151             ptr += sizeof(random_buf);
    152         }
    153         gralloc_unlock_async_img(mpGralloc, (buffer_handle_t)mGrallocHandle, &releaseFence);
    154         if (releaseFence >= 0) {
    155             sync_wait(releaseFence, -1);
    156             close(releaseFence);
    157         }
    158         ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: clear isv buffer %p finished, buffer size %d", __func__, this, buffer_size);
    159         mFlags &= ~ISV_BUFFER_NEED_CLEAR;
    160     }
    161 #endif
    162     return OK;
    163 }
    164 
    165 status_t ISVBufferManager::setBufferCount(int32_t size)
    166 {
    167     Mutex::Autolock autoLock(mBufferLock);
    168 #if 0
    169     if (!mBuffers.isEmpty()) {
    170         ALOGE("%s: the buffer queue should be empty before we set its size", __func__);
    171         return STATUS_ERROR;
    172     }
    173 #endif
    174     mBuffers.setCapacity(size);
    175 
    176     return OK;
    177 }
    178 
    179 status_t ISVBufferManager::freeBuffer(unsigned long handle)
    180 {
    181     Mutex::Autolock autoLock(mBufferLock);
    182     for (uint32_t i = 0; i < mBuffers.size(); i++) {
    183         ISVBuffer* isvBuffer = mBuffers.itemAt(i);
    184         if (isvBuffer->getHandle() == handle) {
    185             delete isvBuffer;
    186             mBuffers.removeAt(i);
    187             ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: remove handle 0x%08lx, and then mBuffers.size() %d", __func__,
    188                     handle, mBuffers.size());
    189             return OK;
    190         }
    191     }
    192 
    193     ALOGW("%s: can't find buffer %lu", __func__, handle);
    194     return UNKNOWN_ERROR;
    195 }
    196 
    197 status_t ISVBufferManager::useBuffer(unsigned long handle)
    198 {
    199     Mutex::Autolock autoLock(mBufferLock);
    200     if (handle == 0 || mBuffers.size() >= mBuffers.capacity())
    201         return BAD_VALUE;
    202 
    203     for (uint32_t i = 0; i < mBuffers.size(); i++) {
    204         ISVBuffer* isvBuffer = mBuffers.itemAt(i);
    205         if (isvBuffer->getHandle() == handle) {
    206             ALOGE("%s: this buffer 0x%08lx has already been registered", __func__, handle);
    207             return UNKNOWN_ERROR;
    208         }
    209     }
    210 
    211     ISVBuffer* isvBuffer = new ISVBuffer(mWorker, handle,
    212                                          mMetaDataMode ? ISVBuffer::ISV_BUFFER_METADATA : ISVBuffer::ISV_BUFFER_GRALLOC,
    213                                          mNeedClearBuffers ? ISVBuffer::ISV_BUFFER_NEED_CLEAR : 0);
    214 
    215     ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG,
    216         "%s: add handle 0x%08lx, and then mBuffers.size() %d", __func__,
    217         handle, mBuffers.size());
    218     mBuffers.push_back(isvBuffer);
    219     return OK;
    220 
    221 }
    222 
    223 status_t ISVBufferManager::useBuffer(const sp<ANativeWindowBuffer> nativeBuffer)
    224 {
    225     Mutex::Autolock autoLock(mBufferLock);
    226     if (nativeBuffer == NULL || mBuffers.size() >= mBuffers.capacity())
    227         return BAD_VALUE;
    228 
    229     for (uint32_t i = 0; i < mBuffers.size(); i++) {
    230         ISVBuffer* isvBuffer = mBuffers.itemAt(i);
    231         if (isvBuffer->getHandle() == (unsigned long)nativeBuffer->handle) {
    232             ALOGE(
    233                 "%s: this buffer 0x%08" PRIxPTR " has already been registered",
    234                 __func__, reinterpret_cast<uintptr_t>(nativeBuffer->handle));
    235             return UNKNOWN_ERROR;
    236         }
    237     }
    238 
    239     ISVBuffer* isvBuffer = new ISVBuffer(mWorker,
    240             (unsigned long)nativeBuffer->handle, (unsigned long)nativeBuffer->handle,
    241             nativeBuffer->width, nativeBuffer->height,
    242             nativeBuffer->stride, nativeBuffer->format,
    243             mMetaDataMode ? ISVBuffer::ISV_BUFFER_METADATA : ISVBuffer::ISV_BUFFER_GRALLOC,
    244             mNeedClearBuffers ? ISVBuffer::ISV_BUFFER_NEED_CLEAR : 0);
    245 
    246     ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG,
    247              "%s: add handle 0x%08" PRIxPTR ", and then mBuffers.size() %d",
    248              __func__, reinterpret_cast<uintptr_t>(nativeBuffer->handle),
    249              mBuffers.size());
    250     mBuffers.push_back(isvBuffer);
    251     return OK;
    252 }
    253 
    254 ISVBuffer* ISVBufferManager::mapBuffer(unsigned long handle)
    255 {
    256     Mutex::Autolock autoLock(mBufferLock);
    257     for (uint32_t i = 0; i < mBuffers.size(); i++) {
    258         ISVBuffer* isvBuffer = mBuffers.itemAt(i);
    259         if (isvBuffer->getHandle() == handle)
    260             return isvBuffer;
    261     }
    262     return NULL;
    263 }
    264 
    265 status_t ISVBufferManager::setBuffersFlag(uint32_t flag)
    266 {
    267     Mutex::Autolock autoLock(mBufferLock);
    268 
    269     if (flag & ISVBuffer::ISV_BUFFER_NEED_CLEAR) {
    270         if (mBuffers.size() == 0)
    271             mNeedClearBuffers = true;
    272         else {
    273             for (uint32_t i = 0; i < mBuffers.size(); i++) {
    274                 ISVBuffer* isvBuffer = mBuffers.itemAt(i);
    275                 isvBuffer->setFlag(ISVBuffer::ISV_BUFFER_NEED_CLEAR);
    276             }
    277         }
    278     }
    279     return OK;
    280 }
    281