android13/vendor/rockchip/hardware/interfaces/rockit/direct/RTSurfaceCallback.cpp

467 lines
13 KiB
C++
Executable File

/*
* Copyright 2018 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 "RTSurfaceCallback"
#include <string.h>
#include <gralloc_priv_omx.h>
#include <ui/GraphicBufferAllocator.h>
#include "RTSurfaceCallback.h"
#include "RockitPlayer.h"
#include "video_tunnel_win.h"
#include "RTVdecExtendFeature.h"
using namespace ::android;
RTSurfaceCallback::RTSurfaceCallback(const sp<IGraphicBufferProducer> &bufferProducer)
: mSidebandHandle(NULL),
mSidebandWin(NULL) {
mNativeWindow = new Surface(bufferProducer, true);
}
RTSurfaceCallback::~RTSurfaceCallback() {
ALOGD("~RTSurfaceCallback(%p) construct", this);
if (mSidebandHandle) {
native_handle_delete((native_handle_t *)mSidebandHandle);
mSidebandHandle = NULL;
}
if (mSidebandWin != NULL) {
rk_vt_win_destroy(&mSidebandWin);
}
if (mNativeWindow.get() != NULL) {
native_window_set_sideband_stream(mNativeWindow.get(), NULL);
mNativeWindow.clear();
}
}
INT32 RTSurfaceCallback::setNativeWindow(const sp<IGraphicBufferProducer> &bufferProducer) {
if (bufferProducer.get() == NULL)
return 0;
if(getNativeWindow() == NULL) {
mNativeWindow = new Surface(bufferProducer, true);
} else {
ALOGD("already set native window");
}
return 0;
}
INT32 RTSurfaceCallback::connect(INT32 mode) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
(void)mode;
if (getNativeWindow() == NULL)
return -1;
return native_window_api_connect(mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
}
INT32 RTSurfaceCallback::disconnect(INT32 mode) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
(void)mode;
if (getNativeWindow() == NULL)
return -1;
// if native window disconnect. we need clear old buffer,
// so we should flush the sideband win for clear buffer maps.
if (mSidebandWin != NULL) {
rk_vt_win_flush(mSidebandWin);
}
return native_window_api_disconnect(mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);;
}
INT32 RTSurfaceCallback::allocateBuffer(RTNativeWindowBufferInfo *info) {
INT32 ret = 0;
buffer_handle_t bufferHandle = NULL;
gralloc_private_handle_t privHandle;
ANativeWindowBuffer *buf = NULL;
vt_buffer_t *vtBuf = NULL;
memset(info, 0, sizeof(RTNativeWindowBufferInfo));
if (mSidebandWin != NULL) {
ret = rk_vt_win_dequeueBufferAndWait(mSidebandWin, &vtBuf);
if (vtBuf) {
bufferHandle = vtBuf->handle;
}
} else {
if (getNativeWindow() == NULL)
return -1;
ret = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
if (buf) {
bufferHandle = buf->handle;
}
}
if (bufferHandle) {
Rockchip_get_gralloc_private((UINT32 *)bufferHandle, &privHandle);
if (mSidebandWin != NULL) {
info->windowBuf = (void *)vtBuf;
} else {
info->windowBuf = (void *)buf;
}
// use buffer_handle binder
info->name = 0xFFFFFFFE;
info->size = privHandle.size;
info->dupFd = privHandle.share_fd;
}
return 0;
}
INT32 RTSurfaceCallback::freeBuffer(void *buf, INT32 fence) {
ALOGV("%s %d buf=%p in", __FUNCTION__, __LINE__, buf);
INT32 ret = 0;
if (mSidebandWin != NULL) {
ret = rk_vt_win_cancelBuffer(mSidebandWin, (vt_buffer_t *)buf);
} else {
if (getNativeWindow() == NULL)
return -1;
ret = mNativeWindow->cancelBuffer(mNativeWindow.get(), (ANativeWindowBuffer *)buf, fence);
}
return ret;
}
INT32 RTSurfaceCallback::remainBuffer(void *buf, INT32 fence) {
ALOGV("%s %d buf=%p in", __FUNCTION__, __LINE__, buf);
INT32 ret = 0;
if (mSidebandWin != NULL) {
ret = rk_vt_win_cancelBuffer(mSidebandWin, (vt_buffer_t *)buf);
} else {
if (getNativeWindow() == NULL)
return -1;
ret = mNativeWindow->cancelBuffer(mNativeWindow.get(), (ANativeWindowBuffer *)buf, fence);
}
return ret;
}
INT32 RTSurfaceCallback::queueBuffer(void *buf, INT32 fence) {
ALOGV("%s %d buf=%p in", __FUNCTION__, __LINE__, buf);
INT32 ret = 0;
if (mSidebandWin != NULL) {
ret = rk_vt_win_queueBuffer(mSidebandWin, (vt_buffer_t *)buf, fence, 0);
} else {
if (getNativeWindow() == NULL)
return -1;
ret = mNativeWindow->queueBuffer(mNativeWindow.get(), (ANativeWindowBuffer *)buf, fence);
}
return ret;
}
INT32 RTSurfaceCallback::dequeueBuffer(void **buf) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
(void)buf;
return 0;
}
INT32 RTSurfaceCallback::dequeueBufferAndWait(RTNativeWindowBufferInfo *info) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
INT32 ret = 0;
buffer_handle_t bufferHandle = NULL;
gralloc_private_handle_t privHandle;
ANativeWindowBuffer *buf = NULL;
vt_buffer_t *vtBuf = NULL;
memset(info, 0, sizeof(RTNativeWindowBufferInfo));
if (mSidebandWin != NULL) {
ret = rk_vt_win_dequeueBufferAndWait(mSidebandWin, &vtBuf);
if (vtBuf) {
bufferHandle = vtBuf->handle;
}
} else {
if (getNativeWindow() == NULL)
return -1;
ret = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
if (buf) {
bufferHandle = buf->handle;
}
}
if (bufferHandle) {
Rockchip_get_gralloc_private((UINT32 *)bufferHandle, &privHandle);
if (mSidebandWin != NULL) {
info->windowBuf = (void *)vtBuf;
} else {
info->windowBuf = (void *)buf;
}
info->dupFd = privHandle.share_fd;
}
return ret;
}
INT32 RTSurfaceCallback::mmapBuffer(RTNativeWindowBufferInfo *info, void **ptr) {
status_t err = OK;
ANativeWindowBuffer *buf = NULL;
void *tmpPtr = NULL;
if (info->windowBuf == NULL || ptr == NULL) {
ALOGE("lockBuffer bad value, windowBuf=%p, &ptr=%p", info->windowBuf, ptr);
return RT_ERR_VALUE;
}
if (mSidebandWin != NULL)
return RT_ERR_UNSUPPORT;
buf = static_cast<ANativeWindowBuffer *>(info->windowBuf);
sp<GraphicBuffer> graphicBuffer(GraphicBuffer::from(buf));
err = graphicBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, &tmpPtr);
if (err != OK) {
ALOGE("graphicBuffer lock failed err - %d", err);
return RT_ERR_BAD;
}
*ptr = tmpPtr;
return RT_OK;
}
INT32 RTSurfaceCallback::munmapBuffer(void **ptr, INT32 size, void *buf) {
status_t err = OK;
(void)ptr;
(void)size;
if (mSidebandWin != NULL)
return RT_ERR_UNSUPPORT;
sp<GraphicBuffer> graphicBuffer(
GraphicBuffer::from(static_cast<ANativeWindowBuffer *>(buf)));
err = graphicBuffer->unlock();
if (err != OK) {
ALOGE("graphicBuffer unlock failed err - %d", err);
return RT_ERR_BAD;
}
return RT_OK;
}
INT32 RTSurfaceCallback::setCrop(
INT32 left,
INT32 top,
INT32 right,
INT32 bottom) {
ALOGV("%s %d in crop(%d,%d,%d,%d)", __FUNCTION__, __LINE__, left, top, right, bottom);
android_native_rect_t crop;
if (mSidebandWin != NULL) {
vt_win_attr_t attr;
rk_vt_win_getAttr(mSidebandWin, &attr);
attr.left = left;
attr.top = top;
attr.right = right;
attr.bottom = bottom;
return rk_vt_win_setAttr(mSidebandWin, &attr);
}
crop.left = left;
crop.top = top;
crop.right = right;
crop.bottom = bottom;
if (getNativeWindow() == NULL)
return -1;
return native_window_set_crop(mNativeWindow.get(), &crop);
}
INT32 RTSurfaceCallback::setUsage(INT32 usage) {
ALOGV("%s %d in usage=0x%x", __FUNCTION__, __LINE__, usage);
if (getNativeWindow() == NULL)
return -1;
return native_window_set_usage(mNativeWindow.get(), usage);;
}
INT32 RTSurfaceCallback::setScalingMode(INT32 mode) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
if (getNativeWindow() == NULL)
return -1;
return native_window_set_scaling_mode(mNativeWindow.get(), mode);;
}
INT32 RTSurfaceCallback::setDataSpace(INT32 dataSpace) {
ALOGV("%s %d in dataSpace=0x%x", __FUNCTION__, __LINE__, dataSpace);
if (getNativeWindow() == NULL)
return -1;
return native_window_set_buffers_data_space(mNativeWindow.get(), (android_dataspace_t)dataSpace);
}
INT32 RTSurfaceCallback::setTransform(INT32 transform) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
if (getNativeWindow() == NULL)
return -1;
return native_window_set_buffers_transform(mNativeWindow.get(), transform);
}
INT32 RTSurfaceCallback::setSwapInterval(INT32 interval) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
(void)interval;
return 0;
}
INT32 RTSurfaceCallback::setBufferCount(INT32 bufferCount) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
if (getNativeWindow() == NULL)
return -1;
return native_window_set_buffer_count(mNativeWindow.get(), bufferCount);
}
INT32 RTSurfaceCallback::setBufferGeometry(
INT32 width,
INT32 height,
INT32 format) {
ALOGV("%s %d in width=%d, height=%d, format=0x%x", __FUNCTION__, __LINE__, width, height, format);
if (getNativeWindow() == NULL)
return -1;
native_window_set_buffers_dimensions(mNativeWindow.get(), width, height);
native_window_set_buffers_format(mNativeWindow.get(), format);
if (mSidebandWin != NULL) {
vt_win_attr_t attr;
rk_vt_win_getAttr(mSidebandWin, &attr);
attr.width = width;
attr.height = height;
attr.format = format;
return rk_vt_win_setAttr(mSidebandWin, &attr);
}
return 0;
}
INT32 RTSurfaceCallback::setSidebandStream(RTSidebandInfo info) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
status_t err = OK;
if (getNativeWindow() == NULL)
return -1;
if (mSidebandWin == NULL) {
vt_win_attr_t attr;
memset(&attr, 0, sizeof(vt_win_attr_t));
attr.struct_size = sizeof(vt_win_attr_t);
attr.struct_ver = 0;
attr.left = info.left;
attr.top = info.top;
attr.right = info.right;
attr.bottom = info.bottom;
attr.usage = info.usage;
attr.width = info.width;
attr.height = info.height;
attr.format = info.format;
attr.data_space = info.dataSpace;
attr.compress_mode = info.compressMode;
attr.transform = info.transform;
attr.buffer_cnt = info.bufferCnt;
attr.remain_cnt = info.remainCnt;
attr.native_window = mNativeWindow.get();
err = rk_vt_win_create(&attr, &mSidebandWin);
if (err != 0) {
ALOGE("sideband winow set attr failed: %s (%d)", strerror(-err), -err);
return err;
}
rk_vt_win_allocSidebandStream(mSidebandWin, &mSidebandHandle);
if (!mSidebandHandle) {
ALOGE("allocate buffer from sideband window failed!");
return -1;
}
err = native_window_set_sideband_stream(mNativeWindow.get(), (native_handle_t *)mSidebandHandle);
if (err != 0) {
ALOGE("native_window_set_sideband_stream failed: %s (%d)", strerror(-err), -err);
return err;
}
}
return 0;
}
buffer_handle_t RTSurfaceCallback::buf2hnl(void *buf) {
buffer_handle_t handle;
if (mSidebandWin) {
handle = ((vt_buffer_t *)buf)->handle;
} else {
handle = ((ANativeWindowBuffer *)buf)->handle;
}
return handle;
}
INT32 RTSurfaceCallback::query(INT32 cmd, INT32 *param) {
ALOGV("%s %d in", __FUNCTION__, __LINE__);
INT32 ret = RT_OK;
switch (cmd) {
case RT_SURFACE_QUERY_MIN_UNDEQUEUED_BUFFERS : {
if (getNativeWindow() == NULL)
return -1;
ret = mNativeWindow->query(mNativeWindow.get(), cmd, param);
} break;
case RT_SURFACE_CMD_SET_HDR_META : {
RTHdrMeta *hdrMeta = (RTHdrMeta *)param;
int64_t offset = (int64_t)hdrMeta->offset;
buffer_handle_t handle = buf2hnl(hdrMeta->buf);
ret = RTVdecExtendFeature::configFrameHdrDynamicMeta(handle, offset);
} break;
case RT_SURFACE_CMD_GET_HDR_META : {
} break;
case RT_SURFACE_CMD_SET_SCALE_META : {
RTScaleMeta *scaleMeta = (RTScaleMeta *)param;
buffer_handle_t handle = buf2hnl(scaleMeta->buf);
ret = RTVdecExtendFeature::configFrameScaleMeta(handle, scaleMeta);
} break;
case RT_SURFACE_CMD_GET_SCALE_META : {
RTScaleMeta *scaleMeta = (RTScaleMeta *)param;
buffer_handle_t handle = buf2hnl(scaleMeta->buf);
scaleMeta->request = RTVdecExtendFeature::checkNeedScale(handle);
} break;
default : {
ret = RT_ERR_UNSUPPORT;
} break;
}
return ret;
}
void* RTSurfaceCallback::getNativeWindow() {
return (void *)mNativeWindow.get();
}