389 lines
12 KiB
C++
Executable File
389 lines
12 KiB
C++
Executable File
/*
|
|
* Copyright (C) 2009 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
//#define LOG_NDEBUG 0
|
|
#define LOG_TAG "CedarXSoftwareRenderer"
|
|
#include <CDX_Debug.h>
|
|
|
|
#include <binder/MemoryHeapBase.h>
|
|
|
|
#if (CEDARX_ANDROID_VERSION < 7)
|
|
#include <binder/MemoryHeapPmem.h>
|
|
#include <surfaceflinger/Surface.h>
|
|
#include <ui/android_native_buffer.h>
|
|
#else
|
|
#include <system/window.h>
|
|
#endif
|
|
|
|
#include <media/stagefright/foundation/ADebug.h>
|
|
#include <media/stagefright/MetaData.h>
|
|
#include <ui/GraphicBufferMapper.h>
|
|
#if (CEDARX_ANDROID_VERSION <= 9)
|
|
#include <gui/ISurfaceTexture.h>
|
|
#else
|
|
#include <gui/Surface.h>
|
|
#endif
|
|
//#include <hardware/hal_public.h>
|
|
#include <ion/ion.h>
|
|
#include "CedarXSoftwareRenderer.h"
|
|
#include <CDX_Common.h>
|
|
|
|
extern "C" {
|
|
extern unsigned int cedarv_address_phy2vir(void *addr);
|
|
}
|
|
namespace EyeseeLinux {
|
|
|
|
CedarXSoftwareRenderer::CedarXSoftwareRenderer(
|
|
const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
|
|
: //mYUVMode(None),
|
|
mNativeWindow(nativeWindow)
|
|
{
|
|
CHECK(meta->findInt32(kKeyColorFormat, &mPixelFormat));
|
|
|
|
//CHECK(meta->findInt32(kKeyScreenID, &screenID));
|
|
//CHECK(meta->findInt32(kKeyColorFormat, &halFormat));
|
|
CHECK(meta->findInt32(kKeyWidth, &mWidth));
|
|
CHECK(meta->findInt32(kKeyHeight, &mHeight));
|
|
CHECK(meta->findInt32(kKeyDisplayWidth, &mCropWidth));
|
|
CHECK(meta->findInt32(kKeyDisplayHeight, &mCropHeight));
|
|
|
|
int32_t nVdecInitRotation; //clock wise.
|
|
int32_t rotationDegrees; //command gpu transform frame buffer clock wise degree.
|
|
if (!meta->findInt32(kKeyRotation, &nVdecInitRotation)) {
|
|
ALOGD("(f:%s, l:%d) find fail nVdecInitRotation[%d]", __FUNCTION__, __LINE__, nVdecInitRotation);
|
|
rotationDegrees = 0;
|
|
}
|
|
else
|
|
{
|
|
switch(nVdecInitRotation)
|
|
{
|
|
case 0:
|
|
{
|
|
rotationDegrees = 0;
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
rotationDegrees = 270;
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
rotationDegrees = 180;
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
rotationDegrees = 90;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
ALOGE("(f:%s, l:%d) fatal error! nInitRotation=%d", __FUNCTION__, __LINE__, nVdecInitRotation);
|
|
rotationDegrees = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
size_t nGpuBufWidth, nGpuBufHeight;
|
|
nGpuBufWidth = mWidth; //ALIGN32(mWidth);
|
|
nGpuBufHeight = mHeight; //ALIGN32(mHeight);
|
|
|
|
CHECK(mNativeWindow != NULL);
|
|
int usage = 0;
|
|
meta->findInt32(kKeyIsDRM, &usage);
|
|
if(usage) {
|
|
ALOGD("(f:%s, l:%d) Be careful! protected video", __FUNCTION__, __LINE__);
|
|
usage = GRALLOC_USAGE_PROTECTED;
|
|
}
|
|
usage |= GRALLOC_USAGE_SW_READ_NEVER /*| GRALLOC_USAGE_SW_WRITE_OFTEN*/
|
|
| GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
|
|
|
|
CHECK_EQ(0,
|
|
native_window_set_usage(
|
|
mNativeWindow.get(),
|
|
usage));
|
|
|
|
CHECK_EQ(0,
|
|
native_window_set_scaling_mode(
|
|
mNativeWindow.get(),
|
|
NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
|
|
mVideoScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
|
|
|
|
CHECK_EQ(0, native_window_set_buffers_geometry(
|
|
mNativeWindow.get(),
|
|
nGpuBufWidth,
|
|
nGpuBufHeight,
|
|
mPixelFormat));
|
|
uint32_t transform;
|
|
switch (rotationDegrees) {
|
|
case 0: transform = 0; break;
|
|
case 90: transform = HAL_TRANSFORM_ROT_90; break;
|
|
case 180: transform = HAL_TRANSFORM_ROT_180; break;
|
|
case 270: transform = HAL_TRANSFORM_ROT_270; break;
|
|
default: transform = 0; break;
|
|
}
|
|
|
|
if (transform) {
|
|
CHECK_EQ(0, native_window_set_buffers_transform(
|
|
mNativeWindow.get(), transform));
|
|
}
|
|
if(nGpuBufWidth!=mCropWidth || nGpuBufHeight!=mCropHeight)
|
|
{
|
|
ALOGD("(f:%s, l:%d) Be careful! need crop gpuFrame![%dx%d], crop[%dx%d]", __FUNCTION__, __LINE__, nGpuBufWidth, nGpuBufHeight, mCropWidth, mCropHeight);
|
|
//Rect crop;
|
|
android_native_rect_t crop;
|
|
crop.left = 0;
|
|
crop.top = 0;
|
|
crop.right = mCropWidth;
|
|
crop.bottom = mCropHeight;
|
|
//mNativeWindow->perform(mNativeWindow.get(), NATIVE_WINDOW_SET_CROP, &crop);
|
|
native_window_set_crop(mNativeWindow.get(), &crop);
|
|
}
|
|
}
|
|
|
|
CedarXSoftwareRenderer::~CedarXSoftwareRenderer()
|
|
{
|
|
}
|
|
|
|
//static int ALIGN(int x, int y) {
|
|
// y must be a power of 2.
|
|
// return (x + y - 1) & ~(y - 1);
|
|
//}
|
|
|
|
int CedarXSoftwareRenderer::control(int cmd, int para, void *pData)
|
|
{
|
|
int ret = NO_ERROR;
|
|
switch(cmd)
|
|
{
|
|
case VIDEORENDER_CMD_SET_CROP:
|
|
{
|
|
android_native_rect_t *pCrop = (android_native_rect_t*)pData;
|
|
ret = native_window_set_crop(mNativeWindow.get(), pCrop);
|
|
break;
|
|
}
|
|
case VIDEORENDER_CMD_SET_SCALING_MODE:
|
|
{
|
|
if (mNativeWindow != NULL)
|
|
{
|
|
if(mVideoScalingMode != para)
|
|
{
|
|
ret = native_window_set_scaling_mode(mNativeWindow.get(), para);
|
|
if (NO_ERROR == ret)
|
|
{
|
|
mVideoScalingMode = para;
|
|
}
|
|
else
|
|
{
|
|
ALOGE("(f:%s, l:%d) fatal error! Failed to set scaling mode: %d", __FUNCTION__, __LINE__, ret);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
ALOGW("undefined command[0x%x]!", cmd);
|
|
ret = UNKNOWN_ERROR;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
void CedarXSoftwareRenderer::render(const void *pObject, size_t size, void *platformPrivate)
|
|
{
|
|
ALOGE("(f:%s, l:%d) fatal error! why call here?", __FUNCTION__, __LINE__);
|
|
}
|
|
|
|
int CedarXSoftwareRenderer::dequeueFrame(ANativeWindowBufferCedarXWrapper *pObject)
|
|
{
|
|
ANativeWindowBuffer *buf;
|
|
//libhwclayerpara_t* pOverlayParam = NULL;
|
|
//Virtuallibhwclayerpara *pVirtuallibhwclayerpara = (Virtuallibhwclayerpara*)pObject;
|
|
ANativeWindowBufferCedarXWrapper *pANativeWindowBuffer = (ANativeWindowBufferCedarXWrapper*)pObject;
|
|
int err;
|
|
|
|
#if (CEDARX_ANDROID_VERSION >=8)
|
|
if ((err = mNativeWindow->dequeueBuffer_DEPRECATED(mNativeWindow.get(), &buf)) != 0)
|
|
{
|
|
ALOGW("(f:%s, l:%d) Surface::dequeueBuffer returned error %d", __FUNCTION__, __LINE__, err);
|
|
return -1;
|
|
}
|
|
CHECK_EQ(0, mNativeWindow->lockBuffer_DEPRECATED(mNativeWindow.get(), buf));
|
|
#else
|
|
if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0)
|
|
{
|
|
LOGW("Surface::dequeueBuffer returned error %d", err);
|
|
return -1;
|
|
}
|
|
CHECK_EQ(0, mNativeWindow->lockBuffer(mNativeWindow.get(), buf));
|
|
#endif
|
|
|
|
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
|
|
|
|
//Rect bounds(ALIGN32(mWidth), ALIGN32(mHeight));
|
|
Rect bounds(mWidth, mHeight);
|
|
|
|
void *dst;
|
|
void *dstPhyAddr = NULL;
|
|
int nIonUserHandle = -1;
|
|
CHECK_EQ(0, mapper.lock(buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
|
|
//dstPhyAddr = getPhysicalAddress(buf, &nIonUserHandle);
|
|
// LOGD("buf->stride:%d, buf->width:%d, buf->height:%d buf->format:%d, buf->usage:%d,WXH:%dx%d dst:%p",
|
|
// buf->stride, buf->width, buf->height, buf->format, buf->usage, mWidth, mHeight, dst);
|
|
pANativeWindowBuffer->width = buf->width;
|
|
pANativeWindowBuffer->height = buf->height;
|
|
pANativeWindowBuffer->stride = buf->stride;
|
|
pANativeWindowBuffer->format = buf->format;
|
|
pANativeWindowBuffer->usage = buf->usage;
|
|
pANativeWindowBuffer->dst = dst;
|
|
pANativeWindowBuffer->dstPhy = dstPhyAddr;
|
|
pANativeWindowBuffer->pObjANativeWindowBuffer = (void*)buf;
|
|
pANativeWindowBuffer->mIonUserHandle = nIonUserHandle;
|
|
return 0;
|
|
}
|
|
|
|
int CedarXSoftwareRenderer::enqueueFrame(ANativeWindowBufferCedarXWrapper *pObject)
|
|
{
|
|
int err;
|
|
ANativeWindowBuffer *buf = (ANativeWindowBuffer*)pObject->pObjANativeWindowBuffer;
|
|
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
|
|
CHECK_EQ(0, mapper.unlock(buf->handle));
|
|
|
|
#if (CEDARX_ANDROID_VERSION >=8)
|
|
if ((err = mNativeWindow->queueBuffer_DEPRECATED(mNativeWindow.get(), buf)) != 0) {
|
|
LOGW("Surface::queueBuffer returned error %d", err);
|
|
}
|
|
buf = NULL;
|
|
#else
|
|
if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf)) != 0) {
|
|
LOGW("Surface::queueBuffer returned error %d", err);
|
|
}
|
|
buf = NULL;
|
|
#endif
|
|
pObject->pObjANativeWindowBuffer = NULL;
|
|
return 0;
|
|
}
|
|
|
|
int CedarXSoftwareRenderer::cancelFrame(ANativeWindowBufferCedarXWrapper *pObject)
|
|
{
|
|
int err;
|
|
ANativeWindowBuffer *buf = (ANativeWindowBuffer*)pObject->pObjANativeWindowBuffer;
|
|
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
|
|
CHECK_EQ(0, mapper.unlock(buf->handle));
|
|
|
|
#if (CEDARX_ANDROID_VERSION >=8)
|
|
if ((err = mNativeWindow->cancelBuffer_DEPRECATED(mNativeWindow.get(), buf)) != 0) {
|
|
ALOGW("Surface::cancelBuffer returned error %d", err);
|
|
}
|
|
buf = NULL;
|
|
#else
|
|
if ((err = mNativeWindow->cancelBuffer(mNativeWindow.get(), buf)) != 0) {
|
|
ALOGW("Surface::cancelBuffer returned error %d", err);
|
|
}
|
|
buf = NULL;
|
|
#endif
|
|
pObject->pObjANativeWindowBuffer = NULL;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#if 0
|
|
void* CedarXSoftwareRenderer::getPhysicalAddress(ANativeWindowBuffer *pANWB, int *pIonUserHandle)
|
|
{
|
|
return NULL;
|
|
uintptr_t phyAddr;
|
|
int nGPUType = 1; //1:mali, 0:img
|
|
uintptr_t PHY_OFFSET = 0x40000000;
|
|
#if (CEDARX_ANDROID_VERSION >= 11)
|
|
ion_user_handle_t handle_ion = 0;
|
|
#else
|
|
struct ion_handle *handle_ion = NULL;
|
|
#endif
|
|
|
|
#if (defined(__CHIP_VERSION_F81))
|
|
#error "wrong chip!"
|
|
#elif (defined(__CHIP_VERSION_F73))
|
|
IMG_native_handle_t* hnd = (IMG_native_handle_t*)(pANWB->handle);
|
|
nGPUType = 0;;
|
|
if(hnd != NULL)
|
|
{
|
|
ion_import(mIonFd, hnd->fd[0], &handle_ion);
|
|
}
|
|
else
|
|
{
|
|
ALOGE("(f:%s, l:%d) fatal error! ANWB->handle[%p]", __FUNCTION__, __LINE__, hnd);
|
|
return NULL;
|
|
}
|
|
#else
|
|
private_handle_t* hnd = (private_handle_t *)(pANWB->handle);
|
|
nGPUType = 1;
|
|
if(hnd != NULL)
|
|
{
|
|
ion_import(mIonFd, hnd->share_fd, &handle_ion);
|
|
}
|
|
else
|
|
{
|
|
ALOGE("(f:%s, l:%d) fatal error! ANWB->handle[%p]", __FUNCTION__, __LINE__, hnd);
|
|
return NULL;
|
|
}
|
|
#endif
|
|
phyAddr = (uintptr_t)ion_getphyadr(mIonFd, handle_ion);
|
|
if(phyAddr >= PHY_OFFSET)
|
|
{
|
|
phyAddr -= PHY_OFFSET;
|
|
}
|
|
if(pIonUserHandle)
|
|
{
|
|
*pIonUserHandle = (int)handle_ion;
|
|
}
|
|
return (void*)phyAddr;
|
|
}
|
|
#endif
|
|
|
|
CedarXLocalRenderer::CedarXLocalRenderer(const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
|
|
: mTarget(new CedarXSoftwareRenderer(nativeWindow, meta))
|
|
{
|
|
}
|
|
int CedarXLocalRenderer::control(int cmd, int para, void *pData)
|
|
{
|
|
return mTarget->control(cmd, para, pData);
|
|
}
|
|
void CedarXLocalRenderer::render(const void *data, size_t size)
|
|
{
|
|
mTarget->render(data, size, NULL);
|
|
}
|
|
int CedarXLocalRenderer::dequeueFrame(ANativeWindowBufferCedarXWrapper *pObject)
|
|
{
|
|
return mTarget->dequeueFrame(pObject);
|
|
}
|
|
int CedarXLocalRenderer::enqueueFrame(ANativeWindowBufferCedarXWrapper *pObject)
|
|
{
|
|
return mTarget->enqueueFrame(pObject);
|
|
}
|
|
|
|
int CedarXLocalRenderer::cancelFrame(ANativeWindowBufferCedarXWrapper *pObject)
|
|
{
|
|
return mTarget->cancelFrame(pObject);
|
|
}
|
|
|
|
CedarXLocalRenderer::~CedarXLocalRenderer()
|
|
{
|
|
delete mTarget;
|
|
mTarget = NULL;
|
|
}
|
|
|
|
} // namespace android
|
|
|